IPhone-Grand Central Dispatch 主线程

我已经成功地在我的应用程序中使用了大中央调度,但是我想知道使用这样的东西真正的优势是什么:

dispatch_async(dispatch_get_main_queue(), ^{ ... do stuff

甚至

dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff

我的意思是,在这两种情况下,您都触发了一个要在主线程上执行的块,即应用程序运行的确切位置,这无助于减少负载。在第一种情况下,您不能控制块何时运行。我见过这样的例子,在你发射之后半秒钟就被执行了。第二种情况,类似于

[self doStuff];

对吧?

我想知道你们怎么想。

145518 次浏览

向主队列发送块通常是从后台队列发出信号,表示某些后台处理已经完成。

- (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_sync

将同步分派块到队列。这将防止在块执行完之前继续执行方法中的其余代码。

我主要使用 dispatch_async到后台队列来处理主队列中的工作,并利用设备可能拥有的任何额外核心。然后 dispatch_async到主线程,如果我需要更新用户界面。

祝你好运

将块从主线程 可以分派到主队列是有用的。它让主队列有机会处理已经排队的其他块,这样就不会简单地阻止其他所有块的执行。

例如,您可以编写一个基本上是单线程的服务器,但仍然处理许多并发连接。只要队列中没有单个块占用太长时间,服务器就会对新请求保持响应。

如果您的程序只是用它的整个生命来响应事件,那么这是很自然的。您只需要将事件处理程序设置为在主队列上运行,然后调用 patch _ main () ,并且可能根本不需要担心线程安全性。

对于 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 更新,启动 spinner,然后从分派队列中获取下一件事情,这是您的实际处理。处理完成后,将调用动画停止,并返回到运行循环,然后用该停止更新 UI。

异步意味着异步,您应该在大多数情况下使用异步。不要在主线程上调用 sync,因为它会锁定你的 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

斯威夫特三,四,五

在主线程上运行代码

DispatchQueue.main.async {
// Your code here
}