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

Dan*_*ark 28 asynchronous objective-c grand-central-dispatch ios

我正在尝试这两种方法:

dispatch_async(dispatch_get_main_queue(),^{
    [self handleClickAsync];
});
Run Code Online (Sandbox Code Playgroud)

[self performSelector:@selector(handleClickAsync) withObject:nil afterDelay:0];
Run Code Online (Sandbox Code Playgroud)

响应按钮按下.

第二个允许UIButton突出显示正如人们期望的那样并handleClickAsync在下一个运行循环中执行(我想:"以后某个时候"肯定).第一个不允许UIButton实例在操作完成之前点亮.

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

Sea*_*ean 42

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

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

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

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

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


小智 27

我认为这会达到你的观点:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
     //bla bla bla
}];
Run Code Online (Sandbox Code Playgroud)