It is strongly recommended not to update UI controls etc from a background thread (e.g. a timer, comms etc). This can be the cause of crashes which are sometimes very hard to identify. Instead use these to force code to be executed on the UI thread (which is always the “main” thread).
Dispatch Async And Dispatch Sync
dispatch_async(dispatch_get_main_queue(), ^{
//Code here to which needs to update the UI in the UI thread goes here
});
The dispatch_async() method starts an asynchronous task. If you want to wait until the method is finished, use dispatch_sync instead (i.e. when you want to execute a block and wait for the results).
Here’s dispatch_sync with a check to see if its necessary first:
if ([NSThread isMainThread])
{
[self MyMethodName];
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
//Update UI in UI thread here
[self MyMethodName];
});
}
Useful Method To Avoid Hang If Thread Is Already Main Thread
This handy method is based on the one here at stackoverflow
void runOnMainQueueWithoutDeadlocking(void (^block)(void))
{
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
Then you use this in your code
runOnMainQueueWithoutDeadlocking(^{
//Do stuff
});
Perform Selector On Main Thread
When you’re using iOS >= 4, you use dispatch_async over this as it the same as like doing waitUntilDone:NO. If you want to wait until the method is finished use dispatch_sync.
However thi sis how it works to call a method on the main thread
[self performSelectorOnMainThread:@selector(MyMethodName) withObject:nil waitUntilDone:NO];
Is This The Main Thread?
if ([NSThread isMainThread])