我一直在使用我的应用程序中的成功,宏大的中央调度,但我想知道使用这样的东西的真正优势是什么:
dispatch_async(dispatch_get_main_queue(), ^{ ... do stuff
甚至
dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff
我的意思是,在这两种情况下,你都要触发一个块来在主线程上执行,确切地说应用程序在哪里运行,这无助于减少负载。在第一种情况下,当块运行时,您没有任何控制权。我已经看到在你开火后半秒执行块的情况。第二种情况,它类似于
[self doStuff];
对?
我想知道你们的想法是什么。
将块分派给主队列通常是从后台队列完成的,以表示某些后台处理已经完成,例如
- (void)doCalculation
{
//you can use any string instead "com.mycompany.myqueue"
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.mycompany.myqueue", 0);
dispatch_async(backgroundQueue, ^{
int result = <some really long calculation that takes seconds to complete>;
dispatch_async(dispatch_get_main_queue(), ^{
[self updateMyUIWithResult:result];
});
});
}
在这种情况下,我们在后台队列上进行了长时间的计算,并且需要在计算完成时更新我们的UI。通常必须从主队列更新UI,因此我们使用第二个嵌套的dispatch_async“发信号”回主队列。
可能还有其他一些示例,您可能希望将其分派回主队列,但通常以这种方式完成,即从分派到后台队列的块中嵌套。
至于为什么你可能想要从主队列调度到主队列......好吧,你通常不会想到你可能会在下一次运行循环时安排一些工作。
从主线程将块分派到主队列可能很有用。它使主队列有机会处理已排队的其他块,这样您就不会简单地阻止执行其他所有操作。
例如,您可以编写一个基本上单线程的服务器,但仍然可以处理许多并发连接。只要队列中没有单个块花费太长时间,服务器就会响应新请求。
如果你的程序什么都不做,而是一生都在回应事件,那么这很自然。您只需将事件处理程序设置为在主队列上运行,然后调用dispatch_main(),您可能根本不需要担心线程安全。
希望我正确地理解你的问题,因为你想知道dispatch_async和dispatch_sync之间的区别?
dispatch_async
将异步调度块到队列。这意味着它会将块发送到队列,而不是等待它返回,然后继续执行方法中的剩余代码。
dispatch_sync
将同步调度块到队列。这将阻止在块完成执行之前不再执行方法中的剩余代码。
我主要使用dispatch_async
到后台队列来完成主队列的工作,并利用设备可能拥有的任何额外内核。然后dispatch_async
到主线程,如果我需要更新UI。
祝好运
一个有用的地方是UI活动,比如在漫长的操作之前设置一个微调器:
- (void) handleDoSomethingButton{
[mySpinner startAnimating];
(do something lengthy)
[mySpinner stopAnimating];
}
将无法正常工作,因为你在漫长的事情中阻止了主线程并且不让UIKit实际启动微调器。
- (void) handleDoSomethingButton{
[mySpinner startAnimating];
dispatch_async (dispatch_get_main_queue(), ^{
(do something lengthy)
[mySpinner stopAnimating];
});
}
将控制返回到运行循环,运行循环将安排UI更新,启动微调器,然后将从调度队列中获取下一个东西,这是您的实际处理。处理完成后,将调用动画停止,然后返回到运行循环,然后使用停止更新UI。
斯威夫特3,4和5
在主线程上运行代码
DispatchQueue.main.async {
// Your code here
}
异步意味着异步,你应该在大多数时候使用它。您永远不应该在主线程上调用同步,因为它会锁定您的UI,直到任务完成。你在Swift中这是一个更好的方法:
runThisInMainThread { () -> Void in
// Run your code like this:
self.doStuff()
}
func runThisInMainThread(block: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), block)
}
它作为我的回购中的标准功能包括在内,请查看:https://github.com/goktugyil/EZSwiftExtensions