2009-10-07 66 views
3

我只是写一些探索性的代码来巩固我的Objective-C的理解和我碰到这个例子中,我没有完全得到来了。我定义这个方法并运行代码:代码示例:为什么我仍然可以访问这个对象NSString的我已经发布了它?

- (NSString *)stringMethod 
{ 
    NSString *stringPointer = [[NSString alloc] initWithFormat:@"string inside stringPointer"]; 
    [stringPointer release]; 
    [stringPointer release]; 
    NSLog(@"retain count of stringPointer is %i", [stringPointer retainCount]); 
    return stringPointer; 
} 

运行的代码,调用此方法后,我注意到一些事情:

  1. 通常情况下,如果我尝试访问东西是后理应dealloced打零保留计数,我得到一个EXC_BAD_ACCESS错误。在这里,我得到一个malloc“double free”错误。这是为什么?

  2. 无论我在代码中添加多少行“[stringPointer release]”,NSLog都会报告保留计数为1.当我添加更多版本时,我只会得到更多的“双倍释放”错误。为什么发布声明不按预期工作?

  3. 虽然我已经过度释放stringPointer,但我收到了一堆“双免费”错误,返回值仍然工作,如果没有任何事情发生(我在主代码中有另一个NSLog报告返回值)。该程序继续正常运行。再次,有人可以解释为什么发生这种情况?

这些例子是相当琐碎,但我试图让这是怎么回事十足的把握。谢谢!

+0

阅读答案后,阅读其他网站,并多玩一点,我开始认为NSStrings不像其他对象那样分开。例如,如果我使用UILabels而不是NSStrings执行相同的操作,那么肯定会发生停止该程序的错误。在我看来,不管你是否“分配”一个NSString,在后台它都被视为一个基元而不是一个对象,而alloc/release语法就是为了一致性。 – iPhoneToucher 2009-10-07 19:07:14

回答

6

你得到一个双无错,因为你释放两次,使两个的dealloc消息。 = P

请,只是因为你释放不并不意味着其在内存地址中的数据被立即销毁头脑。它只被标记为未使用,所以内核知道在将来的某个时刻,它可以自由地用于另一部分数据。在此之前(在您的应用程序空间中完全不确定),数据将保留在那里。

如此反复:释放(和dealloc'ing)在字节级不立即必要的数据销毁。它只是内核的标记。

0

retainCount总是打印一个可能是由优化引起的 - 当发布的通知将被释放时,没有理由将retainCount更新为零(因为此时没有人应该引用该对象),而是更新retainCount只是解除分配它。

3

有两件事情会在这里的。首先,释放对象并不一定会清除对象以前占用的任何内存。它只是表示它是免费的。除非你做别的事情导致内存被重新使用,否则旧数据就会停滞不前。

在NSString的特定情况下,它是一个类集群,这意味着您从alloc/init返回的实际类是NSString的某个具体子类,而不是NSString实例。对于“常量”字符串,这是一个非常轻量级的结构,只保留一个指向C字符串常量的指针。无论你制作多少张文件或多少次释放它,都不会影响指向常量C字符串的指针的有效性。

尝试在这种情况下检查[stringPointer类],以及在可变字符串或实际使用格式字符和参数的格式化字符串的情况下。可能三个人都会有不同的班级。

相关问题