2011-08-20 66 views
3

可能重复:
check retain count保留/释放计数问题。需要澄清

,因为我是用retainrelease计数玩,我遇到了一个情况,我不能够解释。请帮助我更好地理解它:

  • 有一类O。它不包含变量,什么也不做。
  • 有一班Count。它初始化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. 我们开始为1的保留计数,分配初始化序列后
  2. ,再进行人工保留计数上升到2
  3. 然后,我们减少计数,它下降到1
  4. 之后whic h下一个减少.....看起来什么都不做保持计数仍然是1
  5. 此版本引用坏内存并使应用程序崩溃。

请帮助我理解这种行为

回答

4

如果保留计数为1和松开,对象不再有效,而releaseCount财产是没有意义的(且其结果是不可预知的)。

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

使用发布和保留时,您只负责释放您自己的保留。其他物体可能会对有问题的物体执行保留,并且它们将依次释放它们。

如果您使用包含单词alloccopycreate的方法获得对象,则表示该对象上有隐含的retain。否则,你可以假定在当前运行循环之后对象会消失,所以如果你想挂在对象的副本上,你需要执行一个保留。当你完成对象时,做一个发布。

+0

这非常合理。感谢道格 – JAM

1

由于在最近的另一项讯息中提到你应该从来没有真正使用[retainCount]功能!

check retain count

+0

那么,那么......你如何跟踪你的保留数量? – JAM

+1

你不知道。您首先正确管理内存。 – jtbandes

+1

我同意你不应该将它们用于你的应用程序,但它们对于理解事物的工作方式非常有用。而@mac - 你永远不会使用保留计数来决定是否释放一个实例。我会详细解释我的答案。 –

2

其实,保留数是一个可怕的误导性数据,是一个可怕的学习工具。您可以在保留计数计数是你所期望的值的唯一情况是如果:

  • 你继承NSObject的(或创建自己的根类)

  • 不要你的对象传递给任何系统API 在所有

  • 不使用autorelease不断

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

I.e.

请勿调用retainCount!

cocoa memory management guide准确定义应如何管理保留和释放。

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