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

时间:2012-05-03 22:52:41

标签: objective-c ios asynchronous grand-central-dispatch

我正在尝试这两种方法:

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

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

按下按钮。

第二个允许UIButton按照人们的预期突出显示并在下一个运行循环中执行handleClickAsync(我想:“以后某个时间”肯定)。第一个不允许UIButton实例在操作完成之前点亮。

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

2 个答案:

答案 0 :(得分:39)

我相信答案可以在discussion of the main dispatch queue中找到:

  

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

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

  

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

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

答案 1 :(得分:25)

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

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