8

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

启动时的应用程序

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

5 分钟后的应用状态

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

4

2 回答 2

4

我解决了这个问题。在我的情况下,内存压力是由于运行循环循环持续使用内存造成的。该循环每秒执行一次,并处理必须在视图中分析和呈现的数据。另一件事是,该项目最初没有使用 ARC。将项目转换为 ARC 后出现问题。

在项目转换为 ARC 之前,在循环结束时我直接调用了资源释放。当然,使用 ARC,这是自动完成的,问题就是这样。所以对于运行循环的类,我回到了非ARC版本,并使用了手工制作的技巧来释放我使用的资源。

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

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

在自动释放池块结束时,向块内接收到自动释放消息的对象发送释放消息——对象每次在块内发送自动释放消息时都会收到释放消息。

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

与允许 ARC 为您添加保留和释放调用相比,自动释放效率要低得多,而且它可能不安全。Autorelease 将所有对象放入“池”中,然后当您超出范围和/或决定转储池时,它会“耗尽”池并且对象的保留计数减一。

简短的回答:完全忽略 @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

我希望我能帮助其他有同样问题的人。

于 2013-11-03T11:17:26.683 回答
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.
}
于 2015-04-08T12:25:55.633 回答