I’m using the Kiwi testing framework to test an authentication method in my app. The test freezes at a call to dispatch_sync which looks like this:
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_sync(main, ^
{
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationAuthenticationSuccess object:nil userInfo:ret];
});
I’d like to know why it freezes there, if anyone has any hints.
For the second part of your question regarding the hint on the freeze:
When calling
dispatch_syncon a queue, always verify that this queue is not already the current queue (dispatch_get_current_queue()). Becausedispatch_syncwill queue your block on the queue passed as the first parameter, and then will wait for this block to be executed before continuing.So if the
dispatch_get_current_queue()and the queue on which you enqueue your block are the same, namely the main queue in your case, the main queue will block on the call to dispatch_sync until… the main queue as executed the block, but it can’t, as the queue is blocked, and you have a beautiful deadlock here.One solution ([EDIT] up until iOS6):
[EDIT] Be careful,
dispatch_get_current_queue()is only to be used for debugging purposes and never in production. In fact,dispatch_get_current_queueis deprecated since iOS6.1.3.If you are in the specific case of the main queue (which is associated with the main thread only), you may instead test
[NSThread isMainThread]as suggested by @meaning-matters.By the way, are you sure you need to
dispatch_syncin your case?I guess sending your notification a bit later, avoiding to block until it has been sent, is acceptable in your case, so you may also consider using
dispatch_async(instead of usingdispatch_syncand needing the queue comparison condition), which would avoid the deadlock issue too.