避免自动释放的物体,良好做法或过度杀伤?

fuz*_*oat 5 iphone cocoa-touch memory-management objective-c

我对以下内容感到好奇,当我编写代码时,我总是尝试通过坚持使用非自动释放的对象来管理内存.我知道这意味着对象并没有在游泳池中闲逛,但我只是好奇,如果一般这样做是好的做法还是仅仅是矫枉过正?

// User Managed Memory
NSSet *buttonSizes = [[NSSet alloc] initWithObjects:@"Go", @"Going", @"Gone", nil];
[barItemLeft setPossibleTitles:buttonSizes];
[barItemRight setPossibleTitles:buttonSizes];
[buttonSizes release];
Run Code Online (Sandbox Code Playgroud)

.

// Autoreleased Memory
NSSet *buttonSizes = [NSSet setWithObjects:@"Go", @"Going", @"Gone", nil];
[barItemLeft setPossibleTitles:buttonSizes];
[barItemRight setPossibleTitles:buttonSizes];
Run Code Online (Sandbox Code Playgroud)

Dav*_*ong 8

总矫枉过正.如果您仔细阅读相关文档,则不会说您应该避免自动释放对象.它表示当你处于紧密的,对象丰富的循环中时,应该避免使用自动释放池.在这些情况下,您应该明确地(使用retainrelease)管理内存,以确保以摊销方式创建和销毁对象.

iPhone是一个内存受限的环境的论点是真实的,但完全是红色的鲱鱼.Objective-C,使用Foundation和Cocoa框架(虽然当时没有调用它们),在NeXTcube上运行得很好,它有16MB的RAM(可扩展到64).即使是iPhone 3,此时也非常EOL,拥有128MB.

编辑

由于iPhone应用程序是基于runloop的应用程序,因此每次旋转时都会创建并销毁新的自动释放池.这在文档中有明确定义.因此,您必须创建自己的自动释放池的唯一原因是:

  • 产生后台线程,您必须在其中创建自己的池(因为新线程默认情况下没有基本ARPool)
  • 执行一些操作,生成大量自动释放的对象.在这种情况下,创建和排空池将有助于确保临时对象的有限生命周期.

但是,在第二种情况下,建议您尽可能明确地管理内存.这样,当你的操作试图排空一个有几千个物体的游泳池时,你的操作就不会嘎然而止.如果您手动管理内存,则可以逐步释放这些对象,而不是将它们保存为单个一次性版本.您可以通过嵌套ARPools帮助分摊一次性发布,这将有所帮助.

但是,在一天结束时,只做自然感觉,然后(并且只有这样)优化它,如果你有具体的证据表明你需要这样做.

编辑#2

好了,事实证明,有一个建议避免使用autorelease. 该建议位于"iOS应用程序编程指南"的"调整性能和响应性"区域的"分配内存明确"部分.换句话说,如果您正在测量性能问题,请避免使用它.但严重的是:autorelease已经存在了大约20年,并且在计算机上做得很好,比今天的iDevices更慢,更受限制.