iOS 5是否具有垃圾回收功能?

21

从iOS 5开始,我是否不再需要担心内存管理?此外,所有为iOS 4及更早版本编写的程序是否都需要重新编写,以便让iOS代替你管理内存?


为什么它会在iOS 5中可用而在iOS 4中不可用? - user142019
1
阅读 iPhone 开发者连接中有关 ARC 的文档,一切都变得清晰明了......但这不是垃圾回收,它更好(适用于移动设备)。 - Kendall Helmstetter Gelner
2
ARC并不受保密协议约束,因为它是Clang/LLVM的一部分(而Clang/LLVM是开源的)。 - Myron Slaw
我认为使用“更好”这个词是有争议的——它只是不同而已,具有自己的优点和缺点。 </troll> - deanWombourne
1
ARC和GC一样糟糕。知道自己在做什么的程序员不需要任何形式的GC。Obj-C中的内存管理非常简单... - Christian Schnorr
2
@Jenox 是的,真正的程序员使用TextEdit... - Tricertops
3个回答

39

您似乎在谈论其他答案提到的自动引用计数(ARC)。 ARC是一种垃圾回收机制,它可以自动释放内存,但与良好的垃圾回收器有许多不同之处。

首先,它主要是一项编译技术。编译器了解Cocoa的引用计数指南,因此根据规则插入保留和释放操作。它的工作方式就像您自己编写了保留和释放操作一样 - 它只是为您插入这些操作。正常垃圾回收器在程序运行时跟踪程序的内存。

其次,由于它就像保留和释放一样,所以它不能捕获保留循环(如果对象A保留对象B并且对象B保留对象A,而没有其他任何内容引用它们中的任何一个,则它们都将变得不可回收)。您需要采取相同的预防措施来防止它们。

它还使用与自动垃圾回收器不同的资源。 Objective-C使用的垃圾回收器必须扫描未引用的内存并对其进行回收 - 这很昂贵,并且可能会在较慢的系统上导致“卡顿”,但它们只需要偶尔执行此操作,并且理论上甚至可以微调它们的回收周期以匹配程序实际使用其内存的方式。总的来说,垃圾回收程序将比非垃圾回收程序使用更多的内存,并且在GC决定进行回收时会显着减慢速度。另一方面,ARC将“扫描”移动到编译时,并尽快释放可用的内存,但必须不断更新对象引用计数,而不是像收集器那样等待垃圾堆积。


1
@Yar:是的,避免在委托中保留(retain)对象是一个大问题。不过,你应该使用weak来声明未保留(unretained)的属性,而不是assign。至于在setter方法中使用retain:ARC模式下,显式发送retainreleaseautorelease是非法的。你只需要进行赋值操作,编译器会在必要时插入保留和释放操作。 - Chuck
2
@Yar:具体启用版本的细节受NDA保护,而且很可能会发生变化,但它是编译器功能和运行时库的组合,实现了一些功能(特别是弱引用)。目前有两种使用ARC的方法:1)从iOS开发人员计划获取Xcode 4.2;或2)自己下载最新版本的LLVM并将其用作编译器。 - Chuck
这里有没有关于它是否能在iOS 4上运行的答案? - rogerdpack
1
@rogerdpack: https://dev59.com/Xmsz5IYBdhLWcg3wpZry - Chuck
1
最后一段延续了许多谬论。“垃圾收集器必须扫描未引用的内存并进行收集——这很昂贵。”追踪式GC比引用计数快得多。这就是为什么JVM和.NET都使用追踪式GC。“并可能在较慢的系统上导致“卡顿”。”实时GC存在。增量GC很常见。“另一方面,ARC将“扫描”移至编译时期。”ARC在运行时增加引用计数。这就是为什么它如此缓慢。“尽快释放可用内存。”不是这样的。 - J D
显示剩余4条评论

23
在苹果公司的iOS 5公开页面上,他们这样说:

自动引用计数 (ARC)

Objective-C 的自动引用计数 (ARC) 功能使内存管理成为编译器的职责。通过使用新的 Apple LLVM 编译器启用 ARC,您将永远不需要再输入 retain 或 release,从而大大简化了开发过程,同时减少了崩溃和内存泄漏。编译器完全了解您的对象,并在其不再使用时立即释放每个对象,因此应用程序以与以往一样快速、可预测且流畅的性能运行。

这是一个编译器特性;不是操作系统特性,所以我不明白为什么它不能在旧版本上工作。

4
那不是垃圾回收。 - jscs
5
不,这比垃圾回收更好。编译器知道何时以及需要释放哪些内存,因此所有内存管理都像您自己亲手处理一样被照顾到了。相比垃圾回收,它更加高效,因为在应用程序运行时不会使用任何资源。 - Brandon Schlenker
5
延伸Josh的观点,如果您有一些循环性质的对象,这将无法帮助 - 例如,对于最简单的情况,两个相互引用且没有其他东西引用它们的对象。它们的引用计数永远不会减少到零,因此它们将不会被删除。编辑:@Brandon:部分原因是我们使用GC:p - Callum Rogers
5
@Brandon,“编译器知道何时需要释放内存,因此所有内存管理都像你自己做的那样处理。”你的意思是它也处理循环引用?无论如何,引用计数比良好的垃圾收集器慢,对于多线程代码来说非常慢。 - bestsss
3
ARC仍然是引用计数,只不过是自动的。引用计数算法无法检测保留环。循环检测需要更复杂的机制并会增加运行时开销。 - Chuck
显示剩余3条评论

9

自动引用计数(ARC)实现了Objective-C对象和块的自动内存管理,使程序员免于需要显式插入保留和释放操作。

您将不再担心内存管理。有关此主题的公共信息可供使用:

如果规范太严格难以阅读,在简短地说,您需要编辑保留/释放代码以使用ARC,但旧程序仍然兼容。您不应该混合使用两者。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接