Objective-C 中的自动引用计数不能防止或最小化哪种泄漏? [英] What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?

查看:22
本文介绍了Objective-C 中的自动引用计数不能防止或最小化哪种泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Mac 和 iOS 平台中,内存泄漏往往是由未释放的指针引起的.传统上,检查您的分配、副本和保留以确保每个都有相应的发布消息一直是最重要的.

In the Mac and iOS platforms, memory leaks are often caused by unreleased pointers. Traditionally, it has always been of utmost importance to check your allocs, copies and retains to make sure each has a corresponding release message.

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

The toolchain that comes with Xcode 4.2 introduces automatic reference counting (ARC) with the latest version of the LLVM compiler, that totally does away with this problem by getting the compiler to memory-manage your stuff for you. That'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 allocate your own NSAutoreleasePools anymore).

但是有哪些其他内存泄漏不能阻止我仍然需要注意?

But what other memory leaks does it not prevent that I still have to watch out for?

另外,Mac OS X 和 iOS 上的 ARC 与 Mac OS X 上的垃圾收集有什么区别?

As a bonus, what are the differences between ARC on Mac OS X and iOS, and garbage collection on Mac OS X?

推荐答案

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

The primary memory-related problem you'll still need to be aware of is retain cycles. This occurs when one object has a strong pointer to another, but the target object has a strong pointer back to the original. Even when all other references to these objects are removed, they still will hold on to one another and will not be released. This can also happen indirectly, by a chain of objects that might have the last one in the chain referring back to an earlier object.

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

It is for this reason that the __unsafe_unretained and __weak ownership qualifiers exist. The former will not retain any object it points to, but leaves open the possibility of that object going away and it pointing to bad memory, whereas the latter doesn't retain the object and automatically sets itself to nil when its target is deallocated. Of the two, __weak is generally preferred on platforms that support it.

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

You would use these qualifiers for things like delegates, where you don't want the object to retain its delegate and potentially lead to a cycle.

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

Another couple of significant memory-related concerns are the handling of Core Foundation objects and memory allocated using malloc() for types like char*. ARC does not manage these types, only Objective-C objects, so you'll still need to deal with them yourself. Core Foundation types can be particularly tricky, because sometimes they need to be bridged across to matching Objective-C objects, and vice versa. This means that control needs to be transferred back and forth from ARC when bridging between CF types and Objective-C. Some keywords related to this bridging have been added, and Mike Ash has a great description of various bridging cases in his lengthy ARC writeup.

除此之外,还有其他一些不太常见但仍有潜在问题的情况,其中 已发布的规范详细介绍.

In addition to this, there are several other less frequent, but still potentially problematic cases, which the published specification goes into in detail.

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

Much of the new behavior, based on keeping objects around as long as there is a strong pointer to them, is very similar to garbage collection on the Mac. However, the technical underpinnings are very different. Rather than having a garbage collector process that runs at regular intervals to clean up objects no longer being pointed to, this style of memory management relies on the rigid retain / release rules we all need to obey in Objective-C.

ARC 只是将我们多年来不得不做的重复内存管理任务卸载给编译器,这样我们就再也不用担心它们了.这样,您就不会遇到在垃圾收集平台上遇到的停机问题或锯齿状内存配置文件.我在我的垃圾回收 Mac 应用程序中经历了这两种情况,并且很想知道它们在 ARC 下的表现.

ARC simply takes the repetitive memory management tasks we've had to do for years and offloads them to the compiler so we never have to worry about them again. This way, you don't have the halting problems or sawtooth memory profiles experienced on garbage collected platforms. I've experienced both of these in my garbage collected Mac applications, and am eager to see how they behave under ARC.

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

For more on garbage collection vs. ARC, see this very interesting response by Chris Lattner on the Objective-C mailing list, where he lists many advantages of ARC over Objective-C 2.0 garbage collection. I've run into several of the GC issues he describes.

这篇关于Objective-C 中的自动引用计数不能防止或最小化哪种泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆