iPhone – Grand Central调度主线程
我一直在使用成功,在我的应用程序的大中央调度,但我想知道什么是使用这样的事情的真正优势:
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。 更新用户界面通常必须从主队列中完成,因此我们使用第二个嵌套的dispatch_async来“发信号”回到主队列。
可能还有其他一些例子,你可能想把它们分派回主队列,但是通常这样做,即从一个分派到后台队列的块中嵌套。
- 后台处理完成 – >更新用户界面
- 在后台队列上处理的数据块 – >信号主队列以开始下一个块
- 传入的networking数据在后台队列 – >信号主队列消息已经到达
- 等等
至于为什么你可能想要从主队列发送到主队列…嗯,你通常不会,但可以想象,你可能会做一些工作来做下一次的运行循环。
从主线程将块分派到主队列可能很有用。 它使主队列有机会处理已经排队的其他块,这样就不会简单地阻止其他所有的执行。
例如,您可以编写一个基本上单线程的服务器,但仍处理许多并发连接。 只要队列中没有单独的块花费太长时间,服务器就会响应新的请求。
如果你的程序没有做任何事情,而是花费一生的时间回应事件,那么这可能是相当自然的。 您只需将您的事件处理程序设置为在主队列上运行,然后调用dispatch_main(),您可能就不必担心线程安全性。
希望我正确理解你的问题,你想知道dispatch_async和dispatch_sync之间的区别?
dispatch_async
将asynchronous调度块到队列。 这意味着它会将块发送到队列中,而不是等待它返回,然后继续执行方法中剩余的代码。
dispatch_sync
将同步将该块分派到队列中。 这将阻止该方法中剩余代码的执行,直到块完成执行。
我主要使用一个dispatch_async
到后台队列从主队列中取出工作,并利用设备可能具有的任何额外的内核。 然后dispatch_async
主线程,如果我需要更新用户界面。
祝你好运
有用的一个地方是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更新,启动微调,然后将下一个东西closures调度队列,这是你的实际处理。 处理完成后,调用animation停止,然后返回到运行循环,然后用停止更新UI。
asynchronous意味着asynchronous,你应该使用大部分时间。 您不应该在主线程中调用同步,因为它将locking您的用户界面直到任务完成。 你这里是一个更好的方法来做这个在Swift中:
runThisInMainThread { () -> Void in // Run your code like this: self.doStuff() } func runThisInMainThread(block: dispatch_block_t) { dispatch_async(dispatch_get_main_queue(), block) }
它包括在我的回购标准function,检查出来: https : //github.com/goktugyil/EZSwiftExtensions