-1

我正在做的是在分配 obj 和释放这个 obj 之后检查 retainCount。像下面

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    TestClass *ptr = [[TestClass alloc] init];
    NSLog(@"retain count of ptr is %d",[ptr retainCount]);
    [ptr release];  
    NSLog(@"Right after release:::::retain count of ptr is %d",[ptr retainCount]);
}

在控制台上显示后得到的是

2012-05-11 13:51:09.515 memoryManagement[1807:f803] retain count of ptr is 1
2012-05-11 13:51:09.516 memoryManagement[1807:f803] Right after release:::::retain count of ptr is 1

我不明白为什么释放后的retainCount仍然是1。应该是0。

请就这个问题给我建议,并指出我是否在我的代码中犯了错误。

4

4 回答 4

2

Cocoa Club 的第一条规则是:不要使用-retainCount. Cocoa Club 的第二条规则是不要使用-retainCount.

首先,如果你认为你需要它,你几乎肯定不需要它。如果您使用它进行调试,则说明您使用了错误的工具。如果您将它用于应用程序逻辑,那么您的设计就会损坏。

其次,如果你必须问一个关于它的 StackOverflow 问题,你肯定不需要它。

第三,它很微妙,不可靠,可以在你背后做古怪的事情,而且通常会引起比你想象的更多的头痛。我推荐Bill Bumgarner 的博文

于 2012-05-11T18:11:13.343 回答
1

对象的实际保留计数永远不会为零,因为当它为零时,没有任何东西可以引用它,并且它会被释放。但是,内存实际上并没有被清除,而且看起来内部release代码实际上并没有打扰减少计数。

此外,您违反了内存管理规则;你有一个你拥有的对象,然后你释放它。不再允许您通过该指针与该对象进行交互。

这里没什么可看的,也不必费心查看对象的保留计数。

于 2012-05-11T18:20:43.840 回答
1

你有一个比使用retainCount 更糟糕的问题。

永远不要向你释放的对象发送消息——特别是如果你有理由认为它们的 retainCount 真的是 1。也许 release 是这样写的:

-(void) release {
     if ([self retainCount] == 1) {
         [self dealloc];
     }
     else {
        // reduce the retain count
     }
}

在这种情况下,对象就消失了。你发送消息,如果对象仍然存在于已释放的内存中,它会报告 retainCount 为 1——没有人说如果它被释放,释放需要减少它(谁会知道?)。

一旦你调用 release——你承诺永远不会向对象发送消息——如果你违背了你的承诺,任何事情都可能发生。

Apple 文档解释了为什么 retainCount 不是你想象的那样

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html

重要此方法在调试内存管理问题时通常没有价值。因为任何数量的框架对象可能已经保留了一个对象以保存对它的引用,而同时自动释放池可能在一个对象上保存任何数量的延迟释放,所以您不太可能从中获得有用的信息方法。

文档还解释了您有时会看到一个巨大的数字,而不是您认为的 retainCount 应该是什么:

对于永远不会被释放的对象(也就是说,它们的释放方法什么都不做),这个方法应该返回 UINT_MAX。

不过,这与您的情况无关。如果您在初始化后立即在 ptr 上调用 retain,您可能会看到 retainCount 为 2 和 1(或 N 和 N-1),但不能保证这是真的。retainCount 比许多这些答案让你相信的更合乎逻辑,但它不能以你想要的方式可靠地使用。

于 2012-05-11T18:23:00.653 回答
0

永远不要使用retainCount。这是令人困惑的,永远不会给你一个明确的答案。此外,如果您正确遵循内存管理准则,则永远不需要使用 retaincount。

在大多数情况下,它会为您提供模棱两可的输出。例如。[NSString stringwithstring:@"apple"] 有一个垃圾值作为保留计数,如 1124523415 等。

所以,永远不要相信retainCount。

于 2012-05-11T18:07:27.877 回答