objective-c – 为什么不会崩溃?

objective-c – 为什么不会崩溃?,第1张

概述我试图将一个错误缩小到最小可重复的情况,发现了一些奇怪的事情. 考虑这个代码: static NSString *staticString = nil;int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; if (static 我试图将一个错误缩小到最小可重复的情况,发现了一些奇怪的事情.

考虑这个代码:

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. _CFStringAppendFormatAndArgumentsAux()(第5365行)是所有魔法的地方.您可以看到手动通过以查找所有的%替换.如果替换的类型是CFFormatObjectType,描述函数不为零,并且替换尚未被另一个类型处理,则最终只会调用描述复制函数.由于我们已经表明该描述没有被复制,所以可以合理地假定Nsstring处理得更早(在这种情况下,它可能要做一个原始的字节副本),这导致我们相信…
>凯文推测,这里有一个堆栈错误.指向自动释放的字符串的指针被替换成一个不同的对象,这恰好是一个Nsstring.所以,它不会崩溃.奇怪的.但是,如果我们将静态变量的类型更改为其他类型,就像NSArray一样,则会调用-description方法,并且程序会按预期方式崩溃.

如何真正和完全陌生要点凯文是对行为根本原因的最正确的,并且对格雷厄姆的态度来纠正我的谬论.我希望能接受两个答案…

解决方法 我最了解您所看到的是NSLog()复制格式字符串(可能是可变副本),然后解析参数.因为你已经处理了staticString,所以这样就可以将格式化字符串的副本放在同一个位置.这将导致您看到您所描述的“static:static:”输出.当然,这个行为是未定义的 – 不能保证它总是使用相同的内存位置.

另一方面,您的NSLog(@“static:%s”,[staticString UTF8String])在格式字符串复制发生之前正在访问staticString,这意味着它正在访问垃圾内存.

总结

以上是内存溢出为你收集整理的objective-c – 为什么不会崩溃?全部内容,希望文章能够帮你解决objective-c – 为什么不会崩溃?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1253625.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存