也许这是一个愚蠢的问题,但我认为无论如何我都会问它,因为我仍然试图围绕内存管理。
这是:
1
ViewController *tViewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
self.viewController = tViewController;
[tViewController release];
比这更好:
2
self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];
如何以及为何?
修改
好的,首先,我已经安全地发布了我拥有的任何东西。我可以看到这种情况发生了。
但是在第二种情况下,它是一个延期版本,所以如何判断它何时消失?这种autorelease
这种东西让我很困惑。
这不是程序中唯一可能发生此类事件的实例。当我想要一个特定的物体时,我已经创造了活着,直到上帝知道什么时候,我该怎么办?我autorelease
吗?但如果它在错误的时间消失了?那我该怎么办?
答案 0 :(得分:3)
最终结果在两者中是相同的,但他们到达那里的方式是不同的。在这两种情况下,您都要创建一个稍后发布的临时引用。
第一个版本在发布时立即释放实例(确定性) - 虽然因为self.viewController可能是一个强引用,所以实例不会在发布调用时释放。
当取消分配当前自动释放池时,第二个版本在将来的某个时刻(非确定性)释放实例。再次 - 如果self.viewController持有对它的引用将不会被释放。
答案 1 :(得分:1)
两者都是一样的。唯一的区别是1有一个参考[tViewController]来设置实例,而在2中它是直接完成的。
答案 2 :(得分:0)
事情是,在第一种情况下,您手动释放viewController。它立即被摧毁。在第二种情况下,对象在事件循环结束时被销毁。 有时候,如果我在一个具有大量自动释放对象的函数中执行内存消耗 - 我会创建自动释放池,并且每次迭代都会耗尽它。
来自NSAutoreleasePool类参考:
Application Kit在事件循环的每个循环开始时在主线程上创建一个自动释放池,并在最后将其排出,从而释放处理事件时生成的任何自动释放的对象。 /强> 的
答案 3 :(得分:0)
我总是在书中说,第二种方式是更好的方式。但在过去,有些人不同意,尤其是在iOS上。有什么区别?
两个变体都分配一个对象。两种变体都会照顾它。 (“Autorelease是一个版本。”)但是他们在不同的时间点做到了这一点:
release
即时释放对象。(两者:如果没有额外的参考。)
在某些情况下,如果不违反MM规则,则无法release
。最简单的情况是您想要返回已分配的对象。谁应该释放它?创建方法?这将返回可能已取消分配的内容。发送消息的方法?这会使alloc
等+1方法与-1 release
等方法失衡。没办法。
示例:
- (NSString*)fullName
{
NSString *fullName = [[NSString alloc] initWithFormat:@"%@, %@", self.lastName, self.firstName];
return fullName; // Who balance +alloc?
}
通过自动释放对象,您的方法保持平衡并可以安全地返回对象。
在其他情况下,它是摆脱依赖关系的便捷方式。想象一下这段代码:
Person *person = …;
NSString *name = person.name;
[person release], person=nil; // Imagine that this will dealloc the instance.
// name is invalid, because person released it.
使用autorelease
您没有遇到此问题。有几种解决方案:
getter将retain
,autorelease
发送给返回值。 ARP预防中还有一个参考来自dealloction的字符串:
- (NSString*)name
{ return [[_name retain] autorelease]; }
或者使用该方法的那个人做到了:
NSString *name = [[person.name retain] autorelease];
release
问题的下一个问题是,使用return
,break
或continue
更加困难:
while (…)
{
id object = [[Class alloc] …]
if (…)
{
break;
}
[object release];
}
自动释放没有问题。
下一篇:出于某些原因,使用便利分配器(如果存在)是个好主意。从那里返回的对象不允许显式释放,因此放弃引用的代码依赖于引用的设置方式。为什么不一直使用自动释放?
对象删除可能会延迟,因此您可能会遇到内存占用问题。但我个人认为,@autorelease{}
是比release
更好的解决方案。