I have a very weird situation in GCD in my code, and here’s a minimum reproducible code:
<code>
- (void)runMyCode {
__block BOOL completed = NO;
[self doSomethingAsyncAndCompleteOnMainThread:^{
completed = YES;
}];
while (!completed) {
[NSRunLoop.currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.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();
});
}
</code>
<code>
- (void)runMyCode {
__block BOOL completed = NO;
[self doSomethingAsyncAndCompleteOnMainThread:^{
completed = YES;
}];
while (!completed) {
[NSRunLoop.currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.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();
});
}
</code>
- (void)runMyCode {
__block BOOL completed = NO;
[self doSomethingAsyncAndCompleteOnMainThread:^{
completed = YES;
}];
while (!completed) {
[NSRunLoop.currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.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();
});
}
Then when I run directly call my code in viewController
, it completes in 3 seconds.
<code>- (void)viewDidLoad {
[super viewDidLoad];
[self runMyCode];
}
</code>
<code>- (void)viewDidLoad {
[super viewDidLoad];
[self runMyCode];
}
</code>
- (void)viewDidLoad {
[super viewDidLoad];
[self runMyCode];
}
The console prints out “completed”.
However, if I dispatch_async
it to the next run loop, the completion block is not called anymore:
<code>- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^{
[self runMyCode];
});
}
</code>
<code>- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^{
[self runMyCode];
});
}
</code>
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^{
[self runMyCode];
});
}
Nothing gets print out after 3 seconds. Can anyone explain what is wrong with the 2nd example?