我遇到了这个奇怪的错误..基本上我得到了这个块定义:
UILabel* filterButtonLabel;
void (^labelUpdater)(NSString *, id) = ^(NSString* newLabelText, id delegate){
filterButtonLabel.text = newLabelText; // command A
dispatch_after(DISPATCH_SECONDS_FROM_NOW(1), dispatch_get_main_queue(), ^{
[delegate abortFilter]; //command B
});
};
这个块是从工作队列中调用的,如下所示:
dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(taskQ, ^{
[searchWorker withDelegate:self withUpdater:labelUpdater]; //<- worker thread in here
});
updater(@"filter applied", delegate);
(我知道你会问:为什么要委托?别担心,它只是为我省去了很多麻烦,我相信这与这个讨论无关)。
我注意到的事情是command A
这只在完成后执行command B
..这个想法是用用户的一些信息更新 UI..然后在 1 秒后关闭持有该标签的 UI(我想给用户足够的时间阅读通知..知道发生了什么..然后让 UI 自行关闭)。
发生的事情是同时command A
执行和 UI 关闭!如果我将整个调度 after 子句取出..command A
根据需要执行,就是这样。
我也试过这样做:
__block UILabel* filterButtonLabel;
void (^labelUpdater)(NSString *, id) = ^(NSString* newLabelText, id delegate){
filterButtonLabel.text = newLabelText; // command A
dispatch_after(DISPATCH_SECONDS_FROM_NOW(1), dispatch_get_main_queue(), ^{
[delegate abortFilter]; //command B
});
};
我也尝试将队列从更改dispatch_get_main_queue()
为dispatch_get_global_queue()
,反之亦然..仍然没有运气..
想法?
更新(正确答案)
根据下面 Mohannad 的回答..这就是我的最终解决方案的样子(注意:事实证明,命令 A 和命令 B 都涉及 UI 更改。所以两者都应该在主队列中完成。有趣的部分是整个块被放置在一个全局队列中..这增加了他们的执行延迟,我也取出了委托,因为它没有必要)
void (^labelUpdater)(NSString *, id) = ^(NSString* newLabelText){
dispatch_async(dispatch_get_main_queue(), ^ {
filterButtonLabel.text = newLabelText; // command A -> includes a UI change
});
dispatch_after(DISPATCH_SECONDS_FROM_NOW(2), dispatch_get_main_queue(), ^{
[self abortFilter]; //command B -> also includes a UI change
});
};