0

为什么循环中的第二行(a.retainCount 行)不会崩溃(由于访问不正确)?

NSArray* a0 = @[[NSMutableString stringWithString:@"a"]];    
NSArray * arr = [NSArray arrayWithObject:a0];
[a0 release];[a0 release];

for (NSArray* a in arr)
{
    //NSLog(@"%d", (a == a0) );
    NSLog(@"RC: %d", a.retainCount);
}

但如果循环中的第一行(a == a0 one)未注释,它会崩溃。

当自动释放池耗尽时,这肯定会崩溃,但我特别询问循环中的第二行,而不是之后。

谁能解释一下?

4

2 回答 2

5

请查看http://www.whentouseretaincount.com/

向解除分配的对象发送消息是未定义的行为。它可能会崩溃,也可能不会。

在这种情况下,它不会崩溃,因为包含该对象的内存还没有被其他东西覆盖。如果你打开 Malloc Scribble,它会崩溃。该调用NSLog() 巧合地导致内存被乱写,从而导致崩溃。

retainCount永远不能完全返回 0,因为消息传递释放的对象是未定义的行为。系统不会费心将 RC 减至 0,因为无论如何该对象不再可行。

我很好奇这个问题是在什么背景下提出的?您使用的是教程或课堂材料retainCount吗?


出于同样的原因,运行时不会将保留计数减少到 0,它并不总是一个分段错误。效率。

使其成为有保证的分段错误将意味着浪费几个周期将虚假值写入内存(或减少保留计数)。

实际上,free()只需将内存标记为可用于 future malloc()s。它不会以任何方式修改内存的内容,因此是未定义的行为

于 2013-07-01T16:50:38.007 回答
3

这可能随时崩溃。循环中的第一行很可能触发了分配给其他用途的悬空指针“a”处的内存。因此,当第二行引用“a”时,任何事情都可能发生。如果在“Scheme -> Diagnostics -> Memory Management”中打开 XCode 选项,这可能会立即崩溃。

于 2013-07-01T14:35:25.407 回答