响应低内存警告后释放分配,但应用程序仍会崩溃

3
我正在开发一个查看从API拉取下来的照片的应用,每张照片的大小约为1MB。我设置了一种“幻灯片”来显示照片,然后继续显示下一张照片,就像用户实际使用该应用程序一样。我正在iPad 1上使用Instruments进行测试。
当我的应用程序收到低内存警告时,我会将当前未显示给用户的所有照片以及从API返回的所有缓存模型数据都删除。我在Instruments中看到了分配量和虚拟内存使用量的显著下降。尽管消耗的内存有所减少,但我的应用程序仍被操作系统杀死。
应用程序在响应2-3次内存警告后才会崩溃被终止。
我最近切换到ARC,也许有些事情我没有理解?我认为将我的引用设置为nil就足够了。这是我在内存中转储图像数据的代码:
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
    NSLog(@"Received memory warning; clear image for photo named \"%@\"", _name);
        _image = nil;
        _imageThumbnail = nil;
}];

被调用的是哪个方法?我还有一个NSMutableDictionary,当我收到低内存警告时,我会对其调用removeAllObjects方法。在设备控制台中,我得到了以下信息:

Oct  5 19:43:46 unknown configd[25] <Notice>: jetsam: kernel termination snapshot being created
Oct  5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.accessoryd) Exited: Killed: 9
Oct  5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.locationd) Exited: Killed: 9
Oct  5 19:43:46 unknown com.apple.launchd[1] <Notice>: (com.apple.mediaserverd) Exited: Killed: 9
Oct  5 19:43:46 unknown com.apple.launchd[1] <Notice>: (UIKitApplication:com.500px[0xd492]) Exited: Killed: 9
Oct  5 19:43:47 unknown kernel[0] <Debug>: launchd[1996] Builtin profile: accessoryd (sandbox)
Oct  5 19:43:47 unknown ReportCrash[1999] <Error>: libMobileGestalt loadBasebandMobileEquipmentInfo: CommCenter error: 1:45
Oct  5 19:43:47 unknown ReportCrash[1999] <Error>: libMobileGestalt copyInternationalMobileEquipmentIdentity: Could not get mobile equipment info dictionary
Oct  5 19:43:47 unknown ReportCrash[1999] <Error>: Saved crashreport to /Library/Logs/CrashReporter/LowMemory-2011-10-05-194347.plist using uid: 0 gid: 0, synthetic_euid: 0 egid: 0
Oct  5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : <NSThread: 0x1cd31410>{name = (null), num = 1}
Oct  5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : {
        OSMemoryNotificationLevel = 0;
        timestamp = "2011-10-05 23:43:47 +0000";
    }
Oct  5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : <NSThread: 0x1cd31410>{name = (null), num = 1}
Oct  5 19:43:47 unknown DTMobileIS[1655] <Warning>: _memoryNotification : {
        OSMemoryNotificationLevel = 0;
        timestamp = "2011-10-05 23:43:47 +0000";
    }
Oct  5 19:43:48 unknown com.apple.locationd[1997] <Notice>: locationd was started after an unclean shutdown
Oct  5 19:43:49 unknown SpringBoard[29] <Warning>: Application '500px' exited abnormally with signal 9: Killed: 9

这是我的分配/虚拟机工具,直到崩溃为止。

有人知道为什么我的应用程序即使释放了内存也会被终止吗?

2个回答

3
    _image = nil;
    _imageThumbnail = nil;

这只是将指针设置为nil,而不是释放实际的对象。释放对象后,它们将被销毁(如果其保留计数达到0)。

由于您正在使用ARC,请将属性设置为nil


1
我不确定这是否有区别,但在我的ARC代码中,我一直使用合成属性来将变量设置为nil,而不是使用iVar本身。 - tapi
1
仍然没有成功 - 可能是我的代码中还有其他未正确释放内存的问题。在自动引用计数(ARC)或错误释放内存方面是否存在常见陷阱? - Ash Furrow
1
不是真的,如果你使用属性或直接 ivar 赋值将变量设置为 nil(只要它是 @synthesized),那么这并没有什么区别。请参阅 http://clang.llvm.org/docs/AutomaticReferenceCounting.html 章节 4.1.1。 - Alfonso

1
原来在其他地方还有对模型类的引用,即使在内存警告期间释放了图像数据,它们也没有被dealloc。最终模型实例过多导致应用程序崩溃。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接