在arc下释放iOS 5中的内存

时间:2013-02-20 12:20:44

标签: ios xcode memory-leaks

我知道这个问题很多次,但我还没有找到解决方案。我的应用程序按照以下顺序进入视图a-> b-> c-> d-> b。这意味着从视图“d”我不总是回去,并且需要跳转到查看“b”。问题是视图“c”和“d”的记忆不是释放,并且在一些循环(b-> c-> d-> b-> c ......)之后应用程序崩溃。操作的顺序非常重要。我必须提一下,我使用模态segue在视图之间导航。我试过以多种方式释放记忆:

  1. 放入DidRecieveMemoryWarning:_myProperty = nil;
  2. 放入ViewDidUnload:_myProperty = nil;
  3. 将所有属性更改为弱。
  4. 使用@autoreleasepool包装代码。
  5. 没有任何帮助,应用程序崩溃了一段时间后,如何通过“强制”释放视图和记忆?

4 个答案:

答案 0 :(得分:1)

ARC 是因为没有强行释放,让操作系统处理所有版本。您应该使用 xcode instruments 来了解您的应用使用了多少内存。这听起来像你膨胀你的记忆,所以你最好检查一下使用了多少内存,你可以做些什么来优化它,这样分配容量将保持在可接受的限度内。 (例如,在每个图像大小为1Mb的视图中加载1000个图像是完全浪费,并且可能会导致此类崩溃。此示例有意夸大,因此您可以获得该想法)

答案 1 :(得分:1)

Objective-C(主要)使用引用计数内存模型。有手动引用计数和自动引用计数(ARC)。

ARC如何运作

如果您曾经使用手动引用计数并运行clang静态分析器工具,您会发现它在查找内存泄漏方面做得非常出色。这是ARC背后的想法 - 如果分析仪能够很好地发现泄漏,那么为什么不让它执行内存管理呢?

因此,分析在编译时完成,结果代码使用retain和release调用。这是ARC的基础,它是一个很棒的内存模型,在性能和易用性之间取得了很好的平衡。它在移动计算中特别有用,因为与垃圾收集不同,它不需要任何额外的CPU周期或电池消耗。

(注意:ARC还引入了弱引用,这是一种在运行时将悬空指针置零的方法)。

使用ARC并不像垃圾收集那么简单 - 您仍然需要知道引用计数内存模型的工作原理。可能会出现以下问题。

保留周期

内存泄漏的主要原因是保留周期。这是对象A对对象B的引用,对象B对对象A的引用。例如,AirlineFlight包含Passenger,而Passenger有AirlineFlight - >内存泄漏。

这在Cocoa中很常见。另一个例子是ViewController拥有一个视图,而View有一个委托,它是ViewController。听起来有点熟?

为了避免保留周期,其中一个对象必须不保留另一个。最常见的方法是将一个指定为父级,将另一个指定为子级。父母保留孩子,但孩子不保留父母。示例:

查看控制器

@interface MyViewController

@property (nonatomic, strong) MyView* view

@end

查看

@interface MyView

@property (nonatomic, assign) MyViewController* controller

@end

保留周期现已中断,内存泄漏将不再发生。

悬空指针

上面的例子不再有内存泄漏,但可能导致另一个问题 - 悬空指针。视图控制器可能会消失,而视图仍然具有对控制器的引用。对控制器的任何调用现在都会导致崩溃。

有两种方法可以解决这个问题:

  1. 在dealloc方法中取消对控制器的引用。 。 。但可能只是

  2. 使用弱引用,如下所示:

    @property (nonatomic, weak) MyViewController* controller
    
  3. iOS 5及更高版本(或OSX 10.7)有一个小的运行时实用程序,可以跟踪悬空指针,并为您指出它们 - 这些被称为弱引用。

    查找内存泄漏

    有几种方法。

    • 使用clang静态分析器检测保留周期。
    • 使用“工具”工具
    • 我喜欢将log语句放在我的控制器和其他关键类的dealloc方法中,以确保它们被释放。

    寻找悬空指针

    • 使用环境变量NS_ZOMBIES_ENABLED进行编译(或在Xcode中编辑Scheme并单击复选框,它将为您设置此参数)。

    自动发布池

    可能发生的另一个问题是在运行循环中分配的对象太多。 。要更正此问题,您可以在主池中创建另一个自动释放池。

    @autoreleasepool
    {
    
    }
    

    (在您的情况下,我认为这不是问题)。

答案 2 :(得分:0)

我也遇到过这个问题,但我正在为OSX10.8编写一个可可应用程序,而不是iOS。 我发现当我做一些新窗口然后一次又一次关闭时,应用程序内存使用量会一直增加。我看到的窗口似乎每次都是新的。 10MB-> 20MB-> 30MB ... 最后,我直接双击.app文件,然后再次检查活动监视器。事实是它真的变得正常了。在发布模式下运行的应用程序是相同的情况。因此,如果您通过Xcode Run运行应用程序,我认为ARC不会立即在调试模式下释放内存。

答案 3 :(得分:0)

你使用重png图像吗?我前一段时间遇到同样的问题,高度x宽度图像使用RAM的高度x宽度x 4(因为它与GPU共享)。只有我的背景浪费了大约120MB。如果是这种情况,请尝试重新定位图像。