NSLog如何导致代码不崩溃?

Ron*_*gge 10 core-data ios

今天我有一个相当有趣的exc_bad_access崩溃.经过大量挖掘后,我想出了以下信息(在模拟器中运行):

如果我只是运行代码,应用程序会在将数据加载到我的托管对象时随机点随机崩溃.从我所知道的,当我将数据加载到托管对象时,它总是崩溃 - 而不是从我的JSON dict转换为数据到实际使用的对象的部分(从字符串和NSNull到int /浮点数和nils)

随机崩溃当然是邪恶的,所以我试图在调试器中逐步完成这个过程,但这并不可行 - 我正在处理很多对象,所以逐个单步执行它们就没有了工作.所以我决定添加一些NSLog来跟踪这个过程并尝试以这种方式发现一个模式.

立即解决了崩溃.

在这个过程中的任何地方,只有一个NSLog可以防止崩溃.

我最终跟踪了堆栈跟踪并发现了实际问题:我在线程环境中访问托管对象,但不是在关联的MOC的performBlockAndWait:方法中.在那一刻,崩溃对我来说非常明显 - 我很震惊,我之前没有更多的问题.我愿意打赌,在拥有2-3个对象的"小"测试数据集和在那里使用NSLogs调试代码之间,错误在之前被有效掩盖了......但问题仍然存在:

为什么NSLog会阻止应用程序崩溃?一个没有副作用的代码怎么能改变应用程序其余部分的执行?这毫无意义!

das*_*ght 13

令人惊讶的是,这是一个相当普遍的情况:在一个看似无关的地方启用日志记录时,我不止一次看到它会立即解决其他地方的计时问题.

这样做的原因是NSLog,就像许多其他输出函数一样,它具有内部同步.某个互斥锁可以保护NSLogNSLog自身或其使用的I/O库之一的内部缓冲区的访问.此同步使呼叫者可以使用NSLog多个线程.正是这种同步改变了程序的时间,影响了竞争条件并最终解决了崩溃问题.