0

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

applicationDidFinishLaunching

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

xxxxxx 未能及时启动

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

根据场景,我想知道:

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

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

这是否意味着即使它在非主线程中,但它正在记录一些长字符串,导致主线程被阻塞?

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

非常感谢!

4

2 回答 2

6

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

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

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

使用它写日志:

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

我没有对其进行测试,但NSLog您可能需要使用 ASL(asl_*函数族)来代替。

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

于 2012-09-10T05:34:15.660 回答
0

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

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

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

于 2012-09-10T05:52:51.593 回答