28

我正在尝试这两种方法:

dispatch_async(dispatch_get_main_queue(),^{
    [self handleClickAsync];
});

[self performSelector:@selector(handleClickAsync) withObject:nil afterDelay:0];

响应按钮按下。

第二个允许按UIButton预期突出显示并handleClickAsync在下一个运行循环中执行(我想:肯定是“稍后”)。第一个不允许UIButton实例点亮,直到操作完全完成。

使用 GCD 执行此操作的正确方法是什么,或者performSelector仍然是唯一的方法?

4

2 回答 2

44

我相信在主调度队列的讨论中可以找到答案:

此队列与应用程序的运行循环(如果存在)一起使用,以将排队任务的执行与附加到运行循环的其他事件源的执行交错​​。

换句话说,主调度队列设置了一个辅助队列(与由提供的标准事件队列一起UIApplicationMain()处理提交到主队列的块。当队列中存在块时,运行循环将从主事件队列中交替出队任务和调度队列。另一方面,参数的参考说明:delay-performSelector:withObject:afterDelay:

指定延迟为 0 不一定会导致选择器立即执行。选择器仍在线程的运行循环中排队并尽快执行。

UIButton因此,当您使用 perform 选择器时,该操作在主事件队列的末尾排队,并且在队列中它前面的所有内容(可能包括取消突出显示的代码)都已处理后才会执行。但是,当您使用主调度队列时,它会将块添加到辅助队列中,然后假设主队列中没有其他块,则可能会立即处理(即在下一个运行循环中)。在这种情况下,取消突出显示按钮的代码仍然位于主事件队列中,而运行循环处理来自辅助块队列的事件。

于 2012-05-04T14:30:53.303 回答
27

我认为这会触及你的观点:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
     //bla bla bla
}];
于 2012-12-27T06:13:36.660 回答