返回一个自动释放对象是一种抽象的形式 - 开发人员的方便,所以他/她不必考虑返回对象的引用计数 - 因此会导致更少的特定错误类别(尽管您也可以说autorelease池引入了新的类别的错误或复杂性)。它可以真正简化客户端代码,但是,可能会有性能问题。当不需要进行参考操作时,它也可以用作抽象优化 - 考虑对象何时持有返回的实例并且不需要进行保留或复制。尽管链接语句可以被过度使用,但这种做法对于链接语句也很方便。
此外,确定引用计数错误的静态分析器对于这些库和程序中的一些来说是相对较新的。 Autorelease池在ARC之前,对objc对象的引用计数进行多年的静态分析 - 确保您的引用计数正确,现在使用这些工具更简单。他们能够检测到许多错误。
当然,如果您喜欢简单的返回自动释放对象 - 使用ARC,您可以返回更少的自动释放对象,而无需引入抽象的autorelease池错误。
使用统一的所有权语义也简化了程序。如果抽象选择器或选择器集合总是使用相同的语义返回,那么它确实可以简化一些通用形式。例如 - 如果传递给performSelector:
的一组选择器具有不同的所有权返回语义,则会增加很多复杂性。如此统一的所有权归还可以真正简化一些更“通用”的实现。
性能:引用计数操作(保留/释放)可能相当重要 - 尤其是如果您习惯于在较低级别工作。但是,当前的自动释放池实现速度非常快。它们最近被更新了,并且比以前更快。编译器和运行库使用几个特殊的快捷键来降低这些成本。保持autorelease池的大小也是一个好主意 - 特别是在移动设备上。创建一个autorelease池非常快。实际上,您可能会从自动释放操作本身增加零个百分点到几个百分点(即消耗的时间比objc_msgSend
+变体少得多)。有些测试甚至跑得快一点。这不是许多人将从中获得的优化。在典型情况下,它不会成为低挂果实,而且在真实计划中衡量这种变化的效果和地点实际上相对困难 - 基于我在bbum提到下面的变化之后所做的一些测试。所以测试范围有限,但MRC和ARC似乎更好/更快。
因此,如果您正在执行自己的引用计数操作,很多情况都归结于您想要承担的责任级别。对于大多数人来说,它不应该改变他们的写作方式。我认为本地化内存问题,更多确定性的对象破坏,以及更可预测的堆大小是人们可能喜欢的主要原因如果您在现代系统上运行,则返回“拥有”(+1)引用计数。即使如此,在很多情况下,运行时和编译器都会为您减少这个数量(请参阅bbum的答案+1)。尽管自动释放池大约一样快,但我现在不打算比现在更多地使用它们 - 所以仍然有合理的理由尽量减少使用它们,但原因正在减少。
总是有机会忘记释放它。在代码中将分配和释放分离太远是潜在的错误来源。特别是当你在一个函数中分配一些东西作为返回对象时。 – nhahtdh
这是一个所有权问题。在情况1中,自动释放的对象由方法返回,因为它可能属于类或框架,而不是调用者。 – CodaFi