在下一次运行循环中执行:GCD 有什么问题?



我正在尝试这两种方法:

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

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

响应按钮按下。

第二个允许UIButton像人们期望的那样突出显示并在下一个运行循环中执行handleClickAsync(我想:"稍后"肯定(。第一个不允许UIButton实例亮起,直到操作完全完成。

使用GCD的正确方法是什么,还是performSelector仍然是唯一的方法?

我相信

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

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

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

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

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

我认为这会击中你的观点:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
     //bla bla bla
}];

最新更新