Objective c 关于自动释放/释放和[池释放]

Objective c 关于自动释放/释放和[池释放],objective-c,memory-management,nsautoreleasepool,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

这是我的代码:

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],则在向池发送释放消息后,字符串的重新计数仍然为1。但使用[string release]替换[string autorelease],最后字符串的重新计数将为0。我对autorelease的了解是“通过向当前autorelease池发送autorelease消息,将对象添加到当前autorelease池中,以便以后发布”。为什么我向其发送了自动释放消息并释放池,我仍然可以访问该对象。

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

问题是:
重新计数是一个实现细节。你永远不能相信它是任何特定的值。你真正需要考虑的是你是否拥有一件物品

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

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

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

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

drain
与引用计数代码中的
release
同义。我已经尝试过这种方法。但控制台中仍然打印字符串的重新计数为1。从
NSAutoreleasePool
参考:“当自动释放池被解除分配时,它向其所有自动释放的对象发送一条释放消息”是,在向池发送释放消息之前,对象的重新计数为1。据此,在[pool release]之后,它向该对象发送一条释放消息,因此其重新计数为0。它应该被释放。但我试着打印它的保留计数,它仍然是1。@tzzzoz:请参阅我的答案,以了解为什么保留计数仍然是1。谢谢!这有助于我理解Objective-C的内存管理。消息传递解除分配的对象会产生未定义的行为。