为什么自动释放特别危险/昂贵的iPhone应用程序?

e.J*_*mes 14 iphone performance objective-c autorelease

我正在寻找一个主要来源(或一个非常好的解释)来支持在autorelease为iPhone编写软件时使用危险或过于昂贵的说法.

有几个开发人员提出这个说法,我甚至听说Apple不推荐它,但是我还没有找到任何具体的来源来支持它.

SO参考:
autorelease-iphone
为什么这会造成内存泄漏(iPhone)?

注意:从概念的角度来看,我可以看到,这autorelease比简单的调用要贵一些release,但我不认为小的惩罚足以让Apple推荐它.

什么是真实的故事?

Tof*_*eer 11

(不能接受你自己的答案?)

好吧,毕竟,我确实找到了Apple Developer的参考资料,在页面底部附近添加了旁注:

iPhone OS注意:因为在iPhone OS上,应用程序在更受内存限制的环境中执行,所以在应用程序创建许多对象的方法或代码块(例如,循环)中不鼓励使用自动释放池.相反,您应该尽可能明确地释放对象.

尽管如此,这建议谨慎使用自动释放,而不是完全避免使用.

(现在我的评论)

听起来维护池有一定的开销.我读过这篇文章会让我尽可能地避免自动释放,因为我更喜欢一致的东西.如果您在自动释放下有一些内存,而其他内存完全由人工管理,则可能会有点混乱.

  • 文档**不要说**以避免`-autorelease`,他们说要避免`NSAutoreleasePool`.(在"自动释放"之后看到"池"这个词?)原因是当你在受限环境中对大量数据进行大型操作时,使用`-release`是优越的,因为你可以更明确地控制生命周期该对象,从而为您的其余操作释放更多资源.`autorelease`的开销非常小(如果20年前NeXT盒可以处理它,那么iPhone也可以处理) (8认同)

小智 9

使用或不使用自动释放不是问题,因为在某些情况下,自动释放是您通过的唯一方法.问题应该是" 为什么不在所有对象上使用autorelease,而不是使用retain和release? ".

要回答这个问题,您应该首先了解什么是自动释放的正确用途.假设您有一个具有两个属性的类:firstName和lastName.每个人都有一个吸气剂和一个二传手.但是你还需要一个方法来返回fullName,方法是将这两个字符串连接成一个全新的字符串:

- (NSString *) fullName {
   NSString str = [[NSString alloc]initWithFormat:@"%@ %@", firstName, lastName];
   // this is not good until we put [str autorelease];
   return str;
}
Run Code Online (Sandbox Code Playgroud)

这张照片出了什么问题?返回字符串的引用计数为1,因此如果您不想泄漏,调用者应该在完成后释放它.从来电者的角度来看,他只是要求一个房产价值fullName.他没有意识到他得到了一个他应该在使用后释放的全新物体这一事实,并没有提到该类内部持有的NSString!

如果我们把[str release]前面的返回,字符串将被销毁,该方法将返回垃圾!这就是我们使用的地方[str autorelease],以便稍后标记要释放的对象(通常在事件处理完成时).这样调用者得到他的对象,并且不必担心他是否应该释放它.

惯例是在方法将其返回给调用者之前在新对象上调用autorelease.例外的是用与启动名称的方法alloc,newcopy.在这种情况下,调用者知道为他们创建了一个全新的对象,他们有责任在该对象上调用release.

完全用自动释放替换释放是一个坏主意,因为对象会堆积并很快堵塞内存,尤其是在循环中.iPhone上的资源是有限的,因此为了尽量减少内存占用,您有责任在完成后尽快释放对象.


Jon*_*son 5

我不同意完全避免自动释放是明智的.

Cocoa Touch在内部经常使用它,在许多情况下,它是正确分配内存的唯一方法(一个很好的例子是可重用的表视图单元).如果您了解正在发生的事情,自动释放池是您可以使用的一个很好的工具.要记住的主要事情是,直到运行循环中的某个点才会释放块.如果您在没有用户交互的情况下运行紧密循环并且正在堆积自动释放块,则最终将耗尽内存.

自动释放不是垃圾收集的替代品(在iPhone SDK中不可用)并且可能导致令人讨厌的悬挂指针错误(指针似乎仍然很好,然后在某些不可预测的点上变得无效),但在写入时也非常有用清晰易用的代码.考虑以下情况:

[aDictionary writeToFile:
     [documentsDirectory stringByAppendingPathComponent:@"settings.plist"]
              atomically:YES];
Run Code Online (Sandbox Code Playgroud)

路径字符串是作为自动释放对象生成的.我们不需要创建临时对象,因此我们避免了这种开销(并且我们可能忘记释放它).内存将完全释放(无泄漏),只是它将在运行循环中发生.问问自己:在回到用户输入之前,我会分配数百个吗?如果不是(这里就是这种情况),autorelease是一个很好的解决方案,实际上这个用于路径的NSString方法只能使用自动释放的内存.

我同意上述海报,遵循惯例并保持一致是一个非常好的主意.