objective-c – 为什么不会崩溃?
我试图将一个错误缩小到最小可重复的情况,发现了一些奇怪的事情.
考虑这个代码: static NSString *staticString = nil; int main (int argc,const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; if (staticString == nil) { staticString = [[NSArray arrayWithObjects:@"1",@"2",@"3",nil] componentsJoinedByString:@","]; } [pool drain]; NSLog(@"static: %@",staticString); return 0; } 我期待这个代码崩溃.相反,它记录: 2011-01-18 14:41:06.311 EmptyFoundation[61419:a0f] static: static: 但是,如果我将NSLog()更改为: NSLog(@"static: %s",[staticString UTF8String]); 然后它崩溃了. 编辑更多信息: 排水池后: NSLog(@"static: %@",staticString); //this logs "static: static: " NSLog(@"static: %@",[staticString description]); //this crashes 所以显然在字符串上调用一个方法是足够好让它崩溃的.在这种情况下,为什么不记录字符串直接导致它崩溃? NSLog()是否应该调用-description方法? 第二个“静态”来自哪里?为什么这不会崩溃? 结果: Kevin Ballard和Graham Lee都是正确的. Graham在意识到NSLog()并没有调用-description(正如我错误地假设)时是正确的,Kevin几乎绝对是正确的,这是一个复制格式字符串和va_list的一个奇怪的堆栈相关的问题. > NSLogging和NSString不调用-description.格雷厄姆优雅地展现了这一点,如果你跟踪核心基金会的采伐记录,你会发现是这种情况. NSLog内部的任何回溯显示它调用NSLogv => _CFLogvEx => _CFStringCreateWithFormatAndArgumentsAux => _CFStringAppendFormatAndArgumentsAux. 如何真正和完全陌生要点凯文是对行为根本原因的最正确的,并且对格雷厄姆的态度来纠正我的谬论.我希望能接受两个答案… 解决方法
我最了解您所看到的是NSLog()复制格式字符串(可能是可变副本),然后解析参数.因为你已经处理了staticString,所以这样就可以将格式化字符串的副本放在同一个位置.这将导致您看到您所描述的“static:static:”输出.当然,这个行为是未定义的 – 不能保证它总是使用相同的内存位置.
另一方面,您的NSLog(@“static:%s”,[staticString UTF8String])在格式字符串复制发生之前正在访问staticString,这意味着它正在访问垃圾内存. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |