如何调试由于内存压力导致的iOS崩溃

时间:2013-10-08 16:33:43

标签: xcode debugging crash xcode-instruments

我正在使用ARC并且应用程序崩溃说收到内存警告。 我正在设备上直接测试应用程序(带有iOS 7.0.2的iPhone 4),并使用iOS 6 SDK使用XCode 5进行编译。 我使用过苹果乐器,我已经分配了大约20MB的LiveBytes。

App at start

4-5分钟后我的应用程序有30mb的内存。

App status after 5 min

在设备上编译和测试应用程序后,我会在几分钟之后看到崩溃,就在内存警告消息之后。为什么不使用仪器发生碰撞? 但是我试图将这个问题解决一个月并且不能得到礼物,我真的需要帮助。 看起来我没有任何泄漏,但我找不到哪里出错了。 提前感谢任何建议。

2 个答案:

答案 0 :(得分:3)

我解决了这个问题。在我的情况下,内存压力,这是由于运行循环周期的恒定内存使用。循环每秒执行一次,并处理必须在视图中分析和显示的数据。另一件事,该项目最初没有使用ARC。转换项目到ARC后发生了问题。

在将项目转换为ARC之前,在循环结束时,我直接呼吁释放资源。使用ARC当然这是自动完成的,问题就是这样。因此,对于运行循环的类,我返回到非ARC版本,我使用这些技巧手动释放我使用的资源。

自动释放池块提供了一种机制,您可以放弃对象的所有权,但避免立即释放它(例如从方法返回对象时)。通常,您不需要创建自己的自动释放池块,但在某些情况下,您必须或者这样做是有益的。

@autoreleasepool {
    // Code that creates autoreleased objects.
}

在自动释放池块的末尾,在块中接收到自动释放消息的对象被发送一个释放消息 - 一个对象在每次在块中发送自动释放消息时都会收到释放消息。

你可以在代码的任何部分放置一个@autoreleasepool块,但是你真的不应该做我认为你正在做的事情。

自动释放的效率远低于允许ARC为您添加保留和释放呼叫的效率,而且可能不安全。 Autorelease将所有对象放在“池”中,然后当您超出范围和/或每当它决定转储池时,它“消耗”池并且对象的保留计数减1。

简短的回答:完全省略@autorelease块,除非Apple在文档或模板中另有说明(例如,main.m中将包含@autoreleasepool)。

这意味着您的对象可能会在您真正想要它们之前被释放。当你有一个非常紧密的代码循环来实例化然后丢弃大量的对象时,@ autoreleasepool块会更有用。例如,一个for循环,它处理一个巨大的数据库并分配字符串对象,然后使用这些字符串对象来填充您创建的类的实例的属性。在这种情况下,当你在for循环中时,ARC可能无法可靠地释放这些对象,你可能需要创建一个自动释放池。

然而,ARC在紧密循环中没有做正确的事情并不常见。它实际上更像是一个非ARC概念,你使用NSAutoreleasePool并手动排空它。

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

我希望我帮助其他人解决同样的问题。

答案 1 :(得分:0)

 #pragma mark - Received Memory Warning

//memory pressure ios
- (void)didReceiveMemoryWarning
{
   [super didReceiveMemoryWarning];

    if ( [self isViewLoaded] && self.view.window == nil )
    {
        self.view = nil;
    }

    // Dispose of any resources that can be recreated.
}