关于autorelease / release和[pool release]

时间:2012-04-02 08:14:13

标签: objective-c memory-management nsautoreleasepool

这是我的代码:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *string = [[NSString alloc] initWithFormat:@"s"];

[string autorelease];
NSLog(@"retainCount of string is %d", [string retainCount]);

[pool release];
NSLog(@"retainCount of string is %d", [string retainCount]);

当我试图了解自动释放和释放时,我很困惑。 如果使用[string autorelease],在向池发送释放消息后,retainCount的字符串仍为1.但是使用[string release]替换[string autorelease],最后retainCount的字符串将为0.我所知道的autorelease是“将一个对象添加到当前的自动释放池,以便以后通过发送自动释放消息来释放”。为什么我发送了一个autorelease消息并释放了池,我仍然可以访问该对象。

2 个答案:

答案 0 :(得分:3)

事情就是这样:retainCount是一个实现细节。你永远不能依赖它是任何特定的价值。你真正需要考虑的是你是否拥有一个物体。

分配字符串后,您拥有它。当您自动释放字符串时,您不再拥有它,并且当您排空/释放自动释放池时它可能会消失。如果没有其他人拥有它,当您释放自动释放池时消失。 Anywway,在释放自动释放池后,您无法合法地发送字符串消息。

在当前实现中,创建的字符串的保留计数为1.自动释放不会更改保留计数。释放池时,release将发送到其中的所有对象,其中包括您的字符串。发布中的代码如下所示:

if (retainCount == 1)
{
    [self dealloc];
}
else
{
    retainCount--;
}

所以你可以看到保留计数永远不会降到零。您的最终NSLog正常工作,因为字符串使用的内存尚未被回收。

答案 1 :(得分:-1)

您必须使用 [pool drain] 而不是发布消息来释放池中的所有自动释放的对象。此消息将为您调用 [池发布]