I am initiating a background task like this:
UIApplication* application = [UIApplication sharedApplication];
_backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
{
[application endBackgroundTask:_backgroundTask];
_backgroundTask = UIBackgroundTaskInvalid;
}];
The app is sent to background and everything is just fine.
Some time later, certain condition is met, and some object ends up executing this code:
[self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUntilDone:YES];
At that point, the app crashes!
Please note that the object is executing in the main thread in this particular case.
I replaced the above code with this:
dispatch_async(dispatch_get_main_queue(), ^{
[self doSomething];
});
And everything seems to be OK, the crash is gone.
What I can imagine is that the waitUntilDone:YES could be the difference here, but that is only my gut-feeling.
My question is:
Is it allowed to use performSelectorOnMainThread:withObject:waitUntilDone:YES when the app is running in the background?
If that is the case, why is the app crashing and why the dispatch_async solved the issue?
Thanks in advance!
Using performSelectorOnMainThread:withObject:waitUntilDone:YES can be the cause of threading deadlocks. The current thread stops and waits. If the main thread does not finish performing the selector in time, the iOS can kill your app for tying up the main thread for more than the allowed time (usually 10 seconds, sometimes less.)
The dispatch_async(dispatch_get_main_queue... call does not block that way. It always puts an event in the queue and waits its turn and the current thread carries on without stopping.
Without more information about the nature of the crash it is hard to say what happened.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With