0

我知道这个问题问了很多次,但我还没有找到解决方案。我的应用程序按照 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 包装代码。

没有任何帮助,应用程序在一段时间后崩溃,如何通过“强制”释放视图和内存?

4

4 回答 4

1

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

ARC 的工作原理

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

因此,分析是在编译时完成的,并且生成的代码使用保留和释放调用进行检测。这是 ARC 的基础及其出色的内存模型,在性能和易用性之间取得了良好的平衡。它在移动计算中特别有用,因为与垃圾收集不同,它不需要任何额外的 CPU 周期或电池消耗。

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

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

保留周期

内存泄漏的主要原因是保留周期。这就是对象 A 对对象 B 的引用,而对象 B 对对象 A 的引用的地方。例如,AirlineFlight 包含一名乘客,而乘客有一个 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
    

iOS 5 及更高版本(或 OSX 10.7)有一个小的运行时实用程序,可以跟踪悬空指针并为您消除它们 - 这些被称为弱引用。

寻找内存泄漏

有几种方法。

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

寻找悬空指针

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

自动释放池

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

@autoreleasepool
{

}

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

于 2013-06-08T04:03:09.157 回答
1

ARC是为了不强制释放而让操作系统处理所有版本。您应该使用xcode 工具来了解您的应用程序正在使用多少内存。在我看来,你的内存膨胀了,所以最好检查一下正在使用多少内存,以及你可以做些什么来优化它,这样分配容量就会保持在可接受的范围内。(例如,在每个图像大小为 1Mb 的视图中加载 1000 张图像完全是浪费,并且可能会导致这种崩溃。这个例子是故意夸大的,所以你会明白的)

于 2013-02-20T12:27:36.703 回答
0

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

于 2013-06-08T02:03:22.713 回答
0

您是否使用过重的 png 图片?不久前我遇到了同样的问题,高度 x 宽度图像使用 RAM 的高度 x 宽度 x 4(因为它与 GPU 共享)。只有我的背景浪费了大约 120MB。如果是这种情况,请尝试重新调整图像尺寸。

于 2016-03-16T10:54:30.573 回答