I am doing some experiment based on this answer: /a/17921058/767653
This is my minimum reproducible code:
- (void)viewDidLoad {
[super viewDidLoad];
__block BOOL completed = NO;
[self doSomethingAsyncAndCompleteOnMainThread:^{
completed = YES;
}];
while (!completed) {
NSLog(@"Wait for 1 sec");
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
NSLog(@"Completed");
}
- (void)doSomethingAsyncAndCompleteOnMainThread:(void(^)(void))completion {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
completion();
});
}
My understanding is that, this code has a deadlock. Because the completion block is run on main thread, so in order for the completion block to run, viewDidLoad
must return. And in order for viewDidLoad
to return, completion block must be run to toggle the completed
flag (hence circular wait).
However, when I run it, I got this print out:
Wait for 1 sec
Wait for 1 sec
Wait for 1 sec
Completed
Which means there’s no deadlock in this code. Where I did understand wrongly?