问题 在为10.5+写作时,我应该使用Objective-C垃圾收集吗?


在OS X 10.5+环境中编写相当典型的Mac代码时,使用垃圾收集有哪些缺点?

到目前为止,我写的所有其他内容都是10.4兼容或者在iPhone上,所以我对保留/发布变得相当舒服,但现在我正在开发一个更大的项目,只有10.5我只是想知道是否存在是继续使用Objective-C 2.0垃圾收集器的任何缺点。

你们有什么感想?


3072
2017-12-10 17:44


起源



答案:


如果您正在编写新的Cocoa代码并以Mac OS X 10.5为目标,请使用Objective-C垃圾回收。

如果您正在编写可能还需要在iPhone上运行的代码,您可以编写 并测试 通过将代码保存在单独的框架中,使用属性编写代码,可以非常轻松地为这两个模型编写代码 -retain 和 -release 使用,并设置框架和单元测试目标 GC-支持 而不是 GC-只

Xcode将运行您的单元测试包两次,一次启用GC,一次关闭GC,您的框架将在两种执行模型下运行。然后,如果您最终想要将该模型级代码带到iPhone,您可以将其放在以iPhone为目标的静态库中,或直接将其包含在iPhone项目中。

但是,无论您是否考虑在iPhone上运行代码,如果您的应用程序需要Leopard,您肯定应该定位垃圾收集。它将简化开发,Objective-C垃圾收集器的性能非常好。


12
2017-12-11 10:28





如果有可能将您的应用程序移植到iPhone,则不应使用它。

垃圾收集 威力 如果您有特殊用例,会对性能产生负面影响。如果没有GC,您可以精确控制对象的破坏,这不是GC世界的情况。在大多数项目中,打开GC是值得的,因为它不易出错且更容易。

理论没有GC的内存管理总是比使用GC更快,但是,在大多数实际应用中并非如此(因为GC通常比人类更优化)。


2
2017-12-10 17:51



理论上GC可能更快!在程序退出之前系统不需要释放内存就是这种情况 - 然后你得到更快的分配(只是堆下的下一个块)并且永远不会花时间释放内存。 - Kornel
好,当然。但理论上,您始终可以编写一个在非GC环境中管理内存的GC。 ;) - Mehrdad Afshari
不,GC不能像非GC系统那样回收内存。它永远不会知道什么时候回收,直到它收集。它可以混合使用,从堆中分配并在超出范围时释放(类似于using()构造),但不使用“纯”GC。 - gbjbaanb
你的评论是不真实的。在许多情况下,自动收集比手动收集更好。 (因为集合被分组为一个操作,而不是在对象不再使用时进行临时处理。) - jrockway
GC程序中的许多性能损失来自更高的内存要求。更多使用的内存意味着更多的缓存未命中并且它们非常昂贵。此外,GC程序通常不会针对内存重用进行优化编写。但这是一个程序员的问题,因为懒惰并且在技术上与GC无关。 - Lothar


答案:


如果您正在编写新的Cocoa代码并以Mac OS X 10.5为目标,请使用Objective-C垃圾回收。

如果您正在编写可能还需要在iPhone上运行的代码,您可以编写 并测试 通过将代码保存在单独的框架中,使用属性编写代码,可以非常轻松地为这两个模型编写代码 -retain 和 -release 使用,并设置框架和单元测试目标 GC-支持 而不是 GC-只

Xcode将运行您的单元测试包两次,一次启用GC,一次关闭GC,您的框架将在两种执行模型下运行。然后,如果您最终想要将该模型级代码带到iPhone,您可以将其放在以iPhone为目标的静态库中,或直接将其包含在iPhone项目中。

但是,无论您是否考虑在iPhone上运行代码,如果您的应用程序需要Leopard,您肯定应该定位垃圾收集。它将简化开发,Objective-C垃圾收集器的性能非常好。


12
2017-12-11 10:28





如果有可能将您的应用程序移植到iPhone,则不应使用它。

垃圾收集 威力 如果您有特殊用例,会对性能产生负面影响。如果没有GC,您可以精确控制对象的破坏,这不是GC世界的情况。在大多数项目中,打开GC是值得的,因为它不易出错且更容易。

理论没有GC的内存管理总是比使用GC更快,但是,在大多数实际应用中并非如此(因为GC通常比人类更优化)。


2
2017-12-10 17:51



理论上GC可能更快!在程序退出之前系统不需要释放内存就是这种情况 - 然后你得到更快的分配(只是堆下的下一个块)并且永远不会花时间释放内存。 - Kornel
好,当然。但理论上,您始终可以编写一个在非GC环境中管理内存的GC。 ;) - Mehrdad Afshari
不,GC不能像非GC系统那样回收内存。它永远不会知道什么时候回收,直到它收集。它可以混合使用,从堆中分配并在超出范围时释放(类似于using()构造),但不使用“纯”GC。 - gbjbaanb
你的评论是不真实的。在许多情况下,自动收集比手动收集更好。 (因为集合被分组为一个操作,而不是在对象不再使用时进行临时处理。) - jrockway
GC程序中的许多性能损失来自更高的内存要求。更多使用的内存意味着更多的缓存未命中并且它们非常昂贵。此外,GC程序通常不会针对内存重用进行优化编写。但这是一个程序员的问题,因为懒惰并且在技术上与GC无关。 - Lothar


我更喜欢自己处理内存管理,仅仅因为我喜欢这种级别的控制。我从其他语言(C#)的经验中了解到GC不允许你完全忽略内存问题,并且在Cocoa中使用弱引用和回调使用(void *)这样的事情是相同的,其中对象未明确拥有另一个对象。你基本上是为另一组挑战(内存泄漏)。就个人而言,这些天我并不倾向于犯太多内存管理错误,而我所做的那些错误很容易被追踪。

在某些情况下(例如为NSOutlineView实现数据源方法,你不想保留提供给大纲视图的对象)我认为GC会非常有帮助,但我还没有做过用它进行真正的测试。

Apple列出了其他一些优点和缺点 GC编程指南


2
2017-12-10 18:02



手动内存管理是一种不成熟的优化。 - jrockway
他没有做优化。 - mk12
你不是要说,“忽略内存问题,这在Cocoa中是不一样的”? - Dan Rosenstark


GC从10.8开始不推荐使用。采用这种技术实际上从来都不是一个好主意,因为性能和稳定性目标从未得到满足。

“手动”管理内存实际上非常简单,因为管理代码可以在很大程度上被考虑在内。我的代码库有<1%与内存管理相关的代码,并且比它需要的代码大。所以我也对ARC持怀疑态度,因为它所解决的问题是如此之小,以至于即使是相当小的技术问题使得它也不值得。


-1
2017-12-12 15:33



事实并非如此 决不 一个好主意。两种技术都有相同的目标;为两者编写的大多数代码看起来都是一样的,并且在将赋值视为所有权时,它们在概念上是等价的。将内存管理代码的百分比作为其易用性的证明是非常不准确的。当然,随着百分比的增加,错误的可能性会增加,但只需要一行(或一行丢失行)就会引入严重的内存管理错误。
拥有良好的目标并不是一个好主意,通往地狱的道路是善意的,所有这一切。 GC根本就没有正常工作,这就是为什么采用它从来都不是一个好主意。在为ARC辩护时,Chris Lattner描述了GC的缺点: lists.apple.com/archives/objc-language/2011/Jun/msg00013.html  这些缺点总是存在,一旦ARC被引入,它们不会突然出现。这个场地对于证明来说太短了,但是你应用于内存管理的相同论点也适用于所有其他代码,因此你的论点似是而非。 - mpw
记录了GC的缺点;那从来没有问题。保留/释放代码的总行数与支持手动内存管理的参数无关,因为它只需要一个保留周期或其他偶然错误来引入错误。有时候,由于我们投入其中的时间,我们变得依赖某些东西,我们变得不信任新事物。我认为反对使用ARC的惯用现代Objective-C因错误的原因而站在历史的错误一边。