【问题标题】:NSLog runs in main thread(?) blocks main thread when string is too big?当字符串太大时,NSLog 在主线程中运行(?)阻塞主线程?
【发布时间】:2012-09-10 13:52:51
【问题描述】:

我需要在我的应用启动时向服务器发送一些剩余数据,所以在

applicationDidFinishLaunching

我调用了一个将一些核心数据实体转换为 JSON 文本并将其发送到服务器的方法。有时应用程序崩溃是因为:

xxxxxx 未能及时启动

我的第一个想法是我在应用程序启动时正在做某事,这会阻塞主线程,然后我意识到这可能不是问题,因为我正在使用 NSURLConnection 发送异步数据并且不应该阻塞主线程,经过一些测试我发现当数据很大时,应用程序更容易崩溃,因为连接是异步的,唯一可疑的代码是当我从Core Data实体创建JSON文本时,我使用NSLog打印它,并且我尝试使用硬编码的大 json 文件,它总是崩溃,如果我注释掉 NSLog 行,它不会崩溃。

根据场景,我想知道:

  1. 我在想,NSLog 是否在主线程上运行,而不管它在哪个线程中被调用?然后我在 Apple 的文档中找到:

NSLogv 的输出是序列化的,因为一个进程中一次只能有一个线程执行上述写入/日志记录。在下一个线程开始尝试之前,所有写入/记录消息的尝试都已完成。

是不是说即使在非主线程中,但是在记录一些长字符串,导致主线程被阻塞?

  1. NSLog 的字符串大小是否有任何限制(理论上,实际)?硬编码的 JSON 文件为 150KB。

非常感谢!

【问题讨论】:

  • 当我重现这个并在调试模式下运行它时,XCode 冻结并且光标变成彩虹微调器,我必须“强制”XCode。
  • 你为什么要尝试记录 150KB?这完全是荒谬的。

标签: objective-c asynchronous nslog appdelegate


【解决方案1】:

使用 GCD 队列并异步转储您的日志。

大致来说,你需要创建一个串行队列:

lqueue = dispatch_queue_create("com.example.logging", NULL)

用它写日志:

dispatch_async(lqueue, ^{ /* write log here */ })

我没有对其进行测试,但您可能需要使用 ASL(asl_* 系列函数)而不是 NSLog

或者更好的是,只需使用像 https://github.com/robbiehanson/CocoaLumberjack 这样的解决方案,它已经完成了所有这些事情等等。

【讨论】:

    【解决方案2】:

    我认为您的应用正在被 iOS 看门狗计时器杀死。如果您检查错误日志,您应该会看到代码 0x8badf00d。基本上,看门狗计时器会监视应用程序的启动和停止,如果它们花费的时间过长,它就会将它们杀死。它观察的方法之一是 applicationDidFinishLaunching 方法。没有关于您的应用程序必须执行多长时间启动的文档,但只有几秒钟。

    您需要做的是将代码移到另一个方法或后台线程中。 applicationDidFinishLaunching 应该尽快完成。

    在这里搜索 0x8badf00d,您会发现很多关于它的讨论以及组织代码的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-25
      相关资源
      最近更新 更多