Search code examples
objective-casynchronousnslogappdelegate

NSLog runs in main thread(?) blocks main thread when string is too big?


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:

  1. I was thinking that, is NSLog running on main thread regardless of in which thread it is called? Then I found in Apple's doc:

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?

  1. Is there any limitation(theoretical, practical) of the string size for NSLog? The hard-coded JSON file is 150KB.

Thanks a lot!


Solution

  • 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.