自动释放与发布

时间:2010-05-05 20:20:21

标签: iphone objective-c cocoa-touch memory-management

鉴于这两种情况,哪种代码是最佳实践?为什么?

自动释放

loginButton = [[[UIBarButtonItem alloc] initWithTitle:@"Login" 
                                                style:UIBarButtonItemStylePlain 
                                                target:self 
                                                action:@selector(loginButtonClicked:)]
                                                autorelease];
self.navigationItem.rightBarButtonItem = loginButton;

版本

loginButton = [[UIBarButtonItem alloc] initWithTitle:@"Login" 
                                                style:UIBarButtonItemStylePlain 
                                                target:self 
                                                action:@selector(loginButtonClicked:)];
self.navigationItem.rightBarButtonItem = loginButton;
[loginButton release];

7 个答案:

答案 0 :(得分:14)

对于你的例子,它并不重要。就个人而言,我可能会使用第一种情况。这样您就可以在以后添加修改或调试代码,而无需担心移动[loginButton release]行。

答案 1 :(得分:8)

使用自动释放似乎有一种耻辱感(即尽可能优先释放),这就是我通常走第二条路线的原因。但是因为你不在这里循环,所以现在释放与后续自动释放将具有完全相同的效果(因为另一个对象保留了loginButton,它不会被dealloc()编辑)。

但是我应该指出,我的大部分内存泄漏是由于忘记添加释放线造成的,所以最好立即自动发布。

答案 2 :(得分:3)

正如卡尔所说,要么你的情况要好。这是因为UIBarButtunItem对象保留在内存中,因为对它的一个引用保留在self.navigationItem内(假设您使用@property (retain)声明了该属性。)。因此,对于使用自动释放池的常见诽谤,即它在内存中保留不必要的对象直到当前事件循环结束,这里不适用。

答案 3 :(得分:2)

由于iPhone上的内存预算非常紧张,首选方式应该是通过显式发布。这样,在runloop期间自动释放池清空之前,对象不会停留,并且您可以尽可能减少内存占用。

答案 4 :(得分:1)

由于navigationItem保留了它,因此两者最终完全相同。样式方面,自动释放首选从不在其名称中指定alloc或copy的方法返回,但否则由您决定。如果没有单独保留对象,则释放将更快地释放内存。

在发布后设置对nil的引用的代码式问题是一个相关的问题。

答案 5 :(得分:0)

当您向对象发送-autorelease消息时,您将其添加到列表中,并在释放自动释放池时收到-release消息。 -autorelease的全部目的是为您提供一种平衡保留和释放的方法,当其他人可能仍然想要您正在发布的对象时,但是您没有。在您描述的情况下,您提供的第二个示例更好。

答案 6 :(得分:0)

虽然在所提出的场景中,两个案例是相同的,但使用版本(reference )而不是自动释放有一点速度优势。所以当有严格的性能要求时,请使用release