3

可能重复:
检查保留计数

当我在玩时retainrelease计数,我遇到了一种情况,我无法解释。请帮助我更好地理解它:

  • 有一堂课O。它不包含变量,也不做任何事情。
  • 有一个类计数。它初始化O并递增,递减计数
  • 有一个带有 2 个按钮的 UI 笔尖:保留和释放

在此处输入图像描述

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    o = [[O alloc]init]; // At this moment [o retainCount] is 1 as expected
    ....

对于每个 doRetain,按预期计算增量

- (IBAction)doRetain:(id)sender {
    [o retain];

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]];    
    [label setText: result];  
    [result release];

}

每当调用 release 时,计数都会减少

- (IBAction)doRelease:(id)sender {
    [o release];

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]];
    [label setText: result];
   [result release];

}

考虑 1 个保留和 2 个发布

在此处输入图像描述

  1. 在分配初始化序列之后,我们从保留计数 1 开始
  2. 其次是手动保留计数上升到 2
  3. 然后我们减少计数,它下降到 1
  4. 之后下一个减少......似乎什么也没做保留计数仍然是1
  5. 此版本指的是内存不足并导致应用程序崩溃。

请帮助我理解这种行为

4

3 回答 3

4

如果您的保留计数为 1 并且您释放,则该对象不再有效,并且 releaseCount 属性毫无意义(其结果是不可预测的)。

另外,我知道这是一个测试,但是您使用“alloc”创建字符串,但从不释放它们。

使用发布和保留时,您只负责发布您自己的保留。其他对象可能会在相关对象上执行保留,然后它们将依次释放它们。

alloc如果您使用包含单词, copyor的方法获取对象create,则retain该对象隐含。否则,您可以假设该对象将在当前运行循环之后消失,因此如果您想挂在该对象的副本上,则需要执行保留。完成对象后,进行释放。

于 2011-08-20T17:13:02.007 回答
2

实际上,保留计数是一种非常具有误导性的数据,是一种可怕的学习工具。您唯一可以指望保留计数是您期望的值的情况是:

  • 您将 NSObject 子类化(或创建自己的根类)

  • 根本不要将您的对象传递给任何系统 API

  • 永远不要使用autorelease

一旦您违反了这些规则中的任何一条,保留计数就会成为一个实现细节,其值超出您的控制范围。当然,在简单的情况下,它会相对一致。直到它不是,然后您将使用不准确的工具基于错误的假设来调试某些东西。

IE

不要调用retainCount!

可可内存管理指南准确定义了应如何管理保留和释放。

您应该将保留计数视为增量;操作将使其保持不变,或者增加或减少它。如果你导致它增加,你必须减少以放弃所有权。绝对值无关紧要。

于 2011-08-20T17:36:41.103 回答
1

正如在最近的另一篇文章中提到的,你永远不应该真正使用 [retainCount] 函数!

检查保留计数

于 2011-08-20T17:11:09.147 回答