Objective-C中的自动引用计数不会阻止或最小化哪种泄漏?

Bol*_*ock 234 macos memory-leaks objective-c ios automatic-ref-counting

在Mac和iOS平台上,内存泄漏通常是由未发布的指针引起的.传统上,检查您的分配,副本和保留以确保每个都有相应的发布消息始终是至关重要的.

Xcode 4.2附带的工具链引入了最新版本的LLVM编译器的自动引用计数(ARC),通过让编译器为您的内存管理来完全解决这个问题.这非常酷,它确实减少了大量不必要的,平凡的开发时间,并防止了很多粗心的内存泄漏,这些泄漏很容易通过适当的保留/释放平衡来修复.当您为Mac和iOS应用程序启用ARC时,甚至需要以不同方式管理自动释放池(因为您不应再分配自己的NSAutoreleasePools).

但是,其他的内存泄漏它不能阻止我仍然要注意?

作为奖励,Mac OS X和iOS上的ARC与Mac OS X上的垃圾收集有什么区别?

Bra*_*son 261

您仍需要注意的与内存相关的主要问题是保留周期.当一个对象具有指向另一个对象的强指针但目标对象具有返回原始对象的强指针时,会发生这种情况.即使删除了对这些对象的所有其他引用,它们仍将保持彼此并且不会被释放.这也可以通过一系列对象间接发生,这些对象可能具有链中最后一个引用回早期对象的对象.

正是出于这个原因,__unsafe_unretained__weak所有权预选赛存在.前者不会保留它所指向的任何对象,但会留下该对象消失的可能性并指向不良内存,而后者不保留该对象并在其目标被释放时自动将其自身设置为nil.在这两者中,__weak通常在支持它的平台上是优选的.

您可以将这些限定符用于委托之类的事情,您不希望该对象保留其委托并可能导致循环.

另外两个与内存相关的重要问题是Core Foundation对象的处理和使用malloc()类似的类型分配的内存char*.ARC不管理这些类型,只管理Objective-C对象,因此您仍需要自己处理它们.Core Foundation类型可能特别棘手,因为有时它们需要桥接到匹配的Objective-C对象,反之亦然.这意味着当在CF类型和Objective-C之间进行桥接时,需要从ARC来回传输控制.添加了一些与此桥接相关的关键字,Mike Ash在他冗长的ARC写作中对各种桥接案例进行了很好的描述.

除此之外,还有其他一些不太常见但仍有潜在问题的案例,已公布的规范详细介绍了这些案例.

大多数基于保持对象的新行为,只要有强大的指针指向它们,就与Mac上的垃圾收集非常相似.但是,技术基础是非常不同的.这种内存管理方式不依赖于定期运行的垃圾收集器进程来清理不再被指向的对象,而是依赖于我们在Objective-C中需要遵守的严格保留/释放规则.

ARC简单地完成了我们多年来不得不做的重复内存管理任务,并将它们卸载到编译器中,因此我们再也不用担心它们了.这样,您就没有垃圾收集平台上遇到的暂停问题或锯齿内存配置文件.我在垃圾收集的Mac应用程序中经历过这两种情况,并且我很想知道它们在ARC下的行为方式.

有关垃圾收集与ARC的更多信息,请参阅Chris Lattner在Objective-C邮件列表中的这一非常有趣的回复,其中列出了ARC优于Objective-C 2.0垃圾收集的许多优点.我遇到了他描述的几个GC问题.

  • 谢谢你的详细解答.我有同样的问题,我在_unsafe_unretained下定义了一个委托,让我的应用程序崩溃,后来通过改为强固定它,但现在它有内存泄漏.所以,我把它改成了弱点,就像一个魅力. (2认同)

Str*_*pes 14

ARC不会帮助你使用非ObjC内存,例如,如果你有malloc()什么东西,你仍然需要free()它.

performSelector:如果编译器无法确定选择器是什么(编译器将在其上生成警告),则可以欺骗ARC .

ARC还将根据ObjC命名约定生成代码,因此如果混合使用ARC和MRC代码,如果MRC代码不能执行编译器认为名称承诺的内容,则可能会得到令人惊讶的结果.


小智 7

由于以下4个问题,我在应用程序中遇到了内存泄漏:

  1. 在解除视图控制器时,不会使NSTimers无效
  2. 在关闭视图控制器时忘记删除任何观察者到NSNotificationCenter.
  3. 在块中保持对自我的强烈引用.
  4. 在视图控制器属性中使用对委托的强引用

幸运的是,我发现了以下博客文章并能够纠正它们:http://www.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/