因此应用程序崩溃时没有堆栈跟踪或任何异常,我每次都可以复制此崩溃。我的第一个想法是它必须是一个双重版本,在运行僵尸10分钟之后,我无法让应用程序崩溃,甚至没有一次。
在查看Allocations之后,我发现在调用方法时,已分配对象的大小会大幅跳跃。所以我最终在for循环中有一个@autoreleasePool。这个自动释放池修复了崩溃;但是我如何确认这确实是一个内存不足的问题呢? (didRecieveMemoryWarning在崩溃之前的任何时候都没有被调用)
为什么autoreleasePool解决了这个问题?
为什么没有调用RecoryMemoryWarning被调用?是因为应用程序在到达当前runloop结束之前内存不足吗?
- (void)doSomething
{
for (Item *item in self.items)
{
@autoreleasepool
{
// A bunch of initializations here that take a lot of memory
}
}
}
答案 0 :(得分:4)
使用Instruments监控分配,看看它是否在没有自动释放池的情况下上升。
如果崩溃发生得特别快或者您阻止了发生内存通知的队列,您将看不到通知。
Autorelease正在解决这个问题,因为在初始化过程中会创建大量自动释放的对象。在循环退出之前,池不会被耗尽。
答案 1 :(得分:0)
didRecieveMemoryWarning不是异步调用的,你的主线程必须返回NSRunLoop才能获得下一个可能调用didRecieveMemoryWarning的事件。除此之外你甚至无法清理自动释放池中的所有对象,所以如果问题是很多自动释放池的话,你可以做很多事。
答案 2 :(得分:-1)
这是否在UIApplicationMain的同一个线程上运行? for作用域是否使用alloc / init分配了大量对象?是否启用了ARC?
@autorelease pool是堆的一部分,负责在没有显式调用init的情况下分配的对象,例如/ [NSString stringWithFormat:“%@”,format] /或者返回自动释放,如/ < em> [[[NSObject alloc] init] autorelease] /。
问题必定已经消失,因为每次到达循环结束时,它都会执行[pool drain],释放该范围内任何静态分配的对象。我想知道你创建另一个线程来执行这个分配并暂停其间的主线程(可能是UIAlertView?)。当你在另一个autoreleasepool中创建一个autoreleasepool时,第二个可能会陷入第一个,只会在应用程序结束时释放。希望它有所帮助。