为什么这不会崩溃?

时间:2013-07-01 14:05:40

标签: ios objective-c crash exc-bad-access

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

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)未被注释,它就会崩溃。

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

有人可以解释一下吗?

2 个答案:

答案 0 :(得分:5)

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

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

在这种情况下,它不会崩溃,因为包含该对象的内存未被其他内容覆盖。如果你要打开Malloc Scribble,就会崩溃。对NSLog() 的调用恰巧导致内存被潦草地写入,导致崩溃。

retainCount永远不会返回0,因为对已释放的对象进行消息传递是未定义的行为。系统不会将RC减少为0,因为无论如何对象都不再可行。

我很好奇这个问题在什么情况下出现了?您使用的是使用retainCount的教程或课程资料吗?


由于运行时没有将保留计数减少到0,所以它并不总是分段错误;效率

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

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

答案 1 :(得分:3)

这可能会随时崩溃。可能循环中的第一行触发了分配给其他用途的悬挂指针“a”的内存。因此,当第二行引用“a”时,任何事情都可能发生。 如果您打开“方案 - >诊断 - >内存管理”中的XCode选项,则可能会立即崩溃。