当字符串太大时,NSLog在主线程(?)中运行阻塞主线程?

时间:2012-09-10 05:00:10

标签: objective-c asynchronous nslog appdelegate

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

applicationDidFinishLaunching

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

  

xxxxxx无法及时发布

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

根据情景,我想知道:

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

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

    是不是意味着它甚至在非主线程中,但是它记录了一些长字符串,这会导致主线程被阻塞?

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

2 个答案:

答案 0 :(得分:5)

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

粗略地说,您需要创建一个串行队列:

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

使用它写日志:

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

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

或者甚至更好,只需使用像https://github.com/robbiehanson/CocoaLumberjack这样已经完成所有这些工作的解决方案。

答案 1 :(得分:0)

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

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

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