I need to send some left-over data to server when my app starts, so in
applicationDidFinishLaunching
I call a method which convert some Core Data entities to JSON text and send it to server. Sometimes the app crashes because:
xxxxxx failed to launch in time
My first thought is that I am doing something when the app is launching, which blocks the main thread, then I realised this may not be the issue, as I am using NSURLConnection to send the data which is asynchronous and should not block main thread, after some testing I found that when the data is big, the app is easier to crash, since the connection is asynchronous, the only suspicious code is when I created the JSON text from Core Data entities, I use NSLog to print it, and I tried to use a hard coded big json file, it always crashes, if I comment out the NSLog line, it does not crash.
Based on the scenario, I wonder:
Output from NSLogv is serialized, in that only one thread in a process can be doing the writing/logging described above at a time. All attempts at writing/logging a message complete before the next thread can begin its attempts.
does it mean even it is in non-main thread, but it is logging some long string, which lead to the main thread is blocked?
Thanks a lot!
Use a GCD queue and dump your logs asynchronously.
Roughly, you need to create a serial queue:
lqueue = dispatch_queue_create("com.example.logging", NULL)
Write the log using it:
dispatch_async(lqueue, ^{ /* write log here */ })
I didn't test it, but instead of NSLog
you'll probably need to use ASL (asl_*
family of functions).
Or even better, just use some solution like https://github.com/robbiehanson/CocoaLumberjack that already does all this stuff and more.