保留/释放计数问题。需要澄清

时间:2011-08-20 17:08:29

标签: objective-c retaincount

  

可能重复:
  check retain count

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

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

enter image description here

- (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];

}

每当调用释放时,计数减少

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

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

}

考虑1个保留和2个版本

enter image description here

  1. 在alloc init sequence
  2. 之后,我们从保留计数1开始
  3. 其次是手动保留计数最多为2
  4. 然后我们减少计数,然后下降到1
  5. 之后下一次减少.....似乎什么都不做保留计数仍为1
  6. 此版本是指内存不良并导致应用崩溃。
  7. 请帮助我理解这种行为

3 个答案:

答案 0 :(得分:4)

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

另外,我知道这是一个测试,但你用'alloc'创建你的字符串,但从不发布它们。

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

如果使用包含单词alloccopycreate的方法获取对象,则所述对象上会隐含retain。否则,您可以假设对象将在当前运行循环后消失,因此如果要挂起对象的副本,则需要执行保留。完成对象后,请执行发布。

答案 1 :(得分:2)

实际上,保留计数是一个可怕的误导性数据,是一个可怕的学习工具。唯一一次,如果符合以下条件,您可以指望保留计数为您期望的值:

  • 你是NSObject的子类(或者创建你自己的根类)

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

  • 不要使用autorelease

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

即。

不要调用retainCount!

cocoa memory management guide确切地定义了应如何管理保留和发布。

您应该将保留计数视为delta;操作将保持不变或增加或减少它。如果你增加它,你必须减少放弃所有权。绝对值不重要。

答案 2 :(得分:1)

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

check retain count