2012-04-02 111 views
2

这是我的代码:关于自动释放/释放和[池释放]

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],发送释放消息到pool后,字符串的retainCount仍然是1.但是用[string release]来代替[string autorelease],最后string的retainCount将是0.我对autorelease的了解是“通过发送一个autorelease消息将对象添加到当前的自动释放池中供以后发布”。为什么我向它发送一个autorelease消息并释放池,我仍然可以访问该对象。

+1

retainCount永远不会返回零。发送解除分配的对象会产生未定义的行为。 – bbum 2012-04-02 15:21:23

回答

3

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

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

在当前的实现中,字符串的保留计数为1创建。autorelease不会更改保留计数。当池被释放时,release被发送到它的所有对象,包括你的字符串。在发布的代码看起来是这样的:

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

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

+0

谢谢你!这有助于我理解Objective-C的内存管理。 – tzzzoz 2012-04-02 08:50:21

-1

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

+0

'drain'与引用计数代码中的'release'同义。 – JeremyP 2012-04-02 08:28:53

+0

我试过这种方法。但字符串的retainCount仍然在控制台中打印。 – tzzzoz 2012-04-02 08:29:50

+0

从'NSAutoreleasePool'引用:“当释放自动释放池被释放时,它向所有自动释放对象发送释放消息” – trojanfoe 2012-04-02 08:30:29