Objective c 当从后台队列块中调用时,什么会导致通过dispatch_async进行的UI更新失败?

Objective c 当从后台队列块中调用时,什么会导致通过dispatch_async进行的UI更新失败?,objective-c,macos,cocoa,macos-mojave,Objective C,Macos,Cocoa,Macos Mojave,任何人都能理解为什么这段代码可以很好地更新UI: __block NSDictionary *result = nil; dispatch_semaphore_t sema = dispatch_semaphore_create(0); [[SomeService sharedInstance] doSomethingGreatWithReplyBlock:^(NSDictionary * response) { result = response; dispatch_sema

任何人都能理解为什么这段代码可以很好地更新UI:

__block NSDictionary *result = nil;
dispatch_semaphore_t sema = dispatch_semaphore_create(0);

[[SomeService sharedInstance] doSomethingGreatWithReplyBlock:^(NSDictionary * response) {
    result = response;
    dispatch_semaphore_signal(sema);
}];

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

dispatch_async(dispatch_get_main_queue(), ^{
    [self updateDisplay:result];
});
但这个不会吗

__block NSDictionary *result = nil;
[[SomeService sharedInstance] doSomethingGreatWithReplyBlock:^(NSDictionary * response) {
    dispatch_async(dispatch_get_main_queue(), ^{
       [self updateDisplay:response];
    });
}];
这不是完全一样吗?在第一个示例中,我正在等待异步操作使用信号量完成。然后在主队列上调度\u async

在第二个块中,我直接从另一个块(在某个后台队列上运行)中调用dispatch_async(也在主队列上)。这一个仍然调用updateDisplay方法,但是它实际上并没有更新UI。感觉像是一些主线程更新问题,但是[NSThread isMainThread]仍然返回true


我在这里遗漏了什么明显的区别吗?我在这里迷路了,希望你能给我解释一下。我以前从未观察到这种奇怪的行为。

我怀疑队列是问题所在(打开主线程消毒剂以确保)。我怀疑(a)
updateDisplay
没有实际运行(在那里放置一个断点以确保它确实运行),或者(b)
updateDisplay
所依赖的东西存在计时问题。确保在到达该点时,该方法中没有任何内容是
nil
(这两种方法的时间可能略有不同)。在ObjC中,“什么都不做”90%的时间表示“某件事为零”。9%的时间表示“你没有真正调用你认为你做过的事情”,1%表示其他事情。@particleman的观点很好。如果这是在主线程上运行的,那么这将阻塞主线程,这将显著改变计时(这是非法的,但仍然可能发生)。不幸的是,没有任何内容为零,每个日志都是正确的,所有值都匹配,但UI仍然不会更新-(我将检查计时是否是一个问题,感谢您的想法!我认为在主线程上运行信号量代码的要点可以引导我找到解决方案。非常感谢您的提示,出于某种原因,我没有考虑到这一点。仍然不确定它为什么会导致此问题,但我将在周一解决;-)