首页 文章

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

提问于
浏览
231

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

Xcode 4.2附带的工具链引入了最新版本的LLVM compiler的自动引用计数(ARC),通过让编译器为您的内存管理来完全解决这个问题 . 那's pretty cool, and it does cut lots of unnecessary, mundane development time and prevent a lot of careless memory leaks that are easy to fix with proper retain/release balance. Even autorelease pools need to be managed differently when you enable ARC for your Mac and iOS apps (as you shouldn' t再分配你自己的 NSAutoreleasePool ) .

但是其他内存泄漏是否会阻止我仍然需要注意?

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

5 回答

  • 14

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

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

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

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

    除此之外,还有其他一些不那么频繁但仍有潜在问题的案例,这些案例详见published specification .

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

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

    有关垃圾收集与ARC的更多信息,请参阅this very interesting response by Chris Lattner on the Objective-C mailing list,其中列出了ARC优于Objective-C 2.0垃圾收集的许多优点 . 我遇到了他描述的几个GC问题 .

  • 260

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

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

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

  • 0

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

    • 在解除视图控制器时不会使NSTimers无效

    • 在解除视图控制器时忘记删除任何观察者到NSNotificationCenter .

    • 保持对自我的强烈引用块 .

    • 在视图控制器属性中使用对委托的强引用

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

  • 6

    ARC也不会管理CoreFoundation类型 . 你可以'bridge'他们(使用 CFBridgingRelease() ),但前提是你要将它用作Objective-C / Cocoa对象 . 请注意,CFBridgingRelease只是将CoreFoundation保留计数减1并将其移动到Objective-C的ARC .

  • 0

    Xcode 9提供了一个很好的工具来查找这类问题 . 它被称为:“ Debug Memory Graph ” . 使用它你可以按类别找到你泄露的对象,你可以清楚地看到谁拥有它的强引用,通过释放它来解决你的问题 . 它还可以检测内存周期 .

    See more info about how to use it

相关问题