NSLog如何导致代码不崩溃?

时间:2013-04-10 18:49:43

标签: ios core-data

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

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

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

立即解决了这起事故。

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

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

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

2 个答案:

答案 0 :(得分:13)

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

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

答案 1 :(得分:3)

  

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

确实这是有道理的。真。

单个NSLog强制将某些内容打印到您的控制台,它需要几分钟的时间,并且在您对某些线程的处理完成和崩溃之间(可能是由于输入不可用)更多。

您的错误可能是由于异步调用造成的。在完成前一个过程之前,您的下一个过而您的下一个流程需要来自previos流程的数据。 NSLog消耗一些时间。