ios iPhone - Grand Central Dispatch 主线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7905192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iPhone - Grand Central Dispatch main thread
提问by DuckDucking
I have been using with success, grand central dispatch in my apps, but I was wondering what is the real advantage of using something like this:
我一直在成功地使用我的应用程序中的大中央调度,但我想知道使用这样的东西的真正优势是什么:
dispatch_async(dispatch_get_main_queue(), ^{ ... do stuff
or even
甚至
dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff
I mean, in both cases you are firing a block to be executed on the main thread, exactly where the app runs and this will not help to reduce the load. In the first case you don't have any control when the block will run. I have seen cases of blocks being executed half a second after you fire them. The second case, it is similar to
我的意思是,在这两种情况下,您都会触发要在主线程上执行的块,这正是应用程序运行的位置,这无助于减少负载。在第一种情况下,您无法控制块何时运行。我见过在你触发块后半秒执行块的情况。第二种情况,类似于
[self doStuff];
right?
对?
I wonder what do you guys think.
我想知道你们怎么看。
回答by Robin Summerhill
Dispatching a block to the main queue is usually done from a background queue to signal that some background processing has finished e.g.
将块分派到主队列通常是从后台队列完成的,以表示某些后台处理已完成,例如
- (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];
});
});
}
In this case, we are doing a lengthy calculation on a background queue and need to update our UI when the calculation is complete. Updating UI normally has to be done from the main queue so we 'signal' back to the main queue using a second nested dispatch_async.
在这种情况下,我们正在对后台队列进行冗长的计算,并且需要在计算完成后更新我们的 UI。更新 UI 通常必须从主队列完成,因此我们使用第二个嵌套的 dispatch_async 向主队列“发信号”。
There are probably other examples where you might want to dispatch back to the main queue but it is generally done in this way i.e. nested from within a block dispatched to a background queue.
可能还有其他示例,您可能希望分派回主队列,但通常以这种方式完成,即嵌套在分派到后台队列的块中。
- background processing finished -> update UI
- chunk of data processed on background queue -> signal main queue to start next chunk
- incoming network data on background queue -> signal main queue that message has arrived
- etc etc
- 后台处理完成 -> 更新 UI
- 在后台队列上处理的数据块 -> 通知主队列开始下一个数据块
- 后台队列上的传入网络数据 -> 通知主队列消息已到达
- 等等等等
As to why you might want to dispatch to the main queue fromthe main queue... Well, you generally wouldn't although conceivably you might do it to schedule some work to do the next time around the run loop.
至于为什么你可能想要从主队列分派到主队列......好吧,你通常不会,尽管可以想象你可能会安排一些工作在下一次运行循环中完成。
回答by bames53
Dispatching blocks to the main queue from the main thread canbe useful. It gives the main queue a chance to handle other blocks that have been queued so that you're not simply blocking everything else from executing.
从主线程调度块到主队列可以是有用的。它使主队列有机会处理已排队的其他块,这样您就不会简单地阻止其他所有内容的执行。
For example you could write an essentially single threaded server that nonetheless handles many concurrent connections. As long as no individual block in the queue takes too long the server stays responsive to new requests.
例如,您可以编写一个本质上是单线程的服务器,它仍然可以处理许多并发连接。只要队列中没有单独的块花费太长时间,服务器就会对新请求保持响应。
If your program does nothing but spend its whole life responding to events then this can be quite natural. You just set up your event handlers to run on the main queue and then call dispatch_main(), and you may not need to worry about thread safety at all.
如果你的程序除了用它的整个生命来响应事件之外什么都不做,那么这可能是很自然的。您只需将事件处理程序设置为在主队列上运行,然后调用 dispatch_main(),您可能根本不需要担心线程安全。
回答by timthetoolman
Hopefully I'm understanding your question correctly in that you are wondering about the differences between dispatch_async and dispatch_sync?
希望我正确理解您的问题,因为您想知道 dispatch_async 和 dispatch_sync 之间的区别?
dispatch_async
will dispatch the block to a queue asynchronously. Meaning it will send the block to the queue and not wait for it to return before continuing on the execution of the remaining code in your method.
将块异步调度到队列中。这意味着它会将块发送到队列,而不是在继续执行方法中剩余的代码之前等待它返回。
dispatch_sync
will dispatch the block to a queue synchronously. This will prevent any more execution of remaining code in the method until the block has finished executing.
将块同步分派到队列。这将阻止在该块完成执行之前继续执行该方法中剩余的代码。
I've mostly used a dispatch_async
to a background queue to get work off the main queue and take advantage of any extra cores that the device may have. Then dispatch_async
to the main thread if I need to update the UI.
我主要使用dispatch_async
后台队列来完成主队列的工作,并利用设备可能拥有的任何额外内核。dispatch_async
如果我需要更新 UI,则转到主线程。
Good luck
祝你好运
回答by weaselfloss1
One place where it's useful is for UI activities, like setting a spinner before a lengthy operation:
一个有用的地方是 UI 活动,比如在冗长的操作之前设置一个微调器:
- (void) handleDoSomethingButton{
[mySpinner startAnimating];
(do something lengthy)
[mySpinner stopAnimating];
}
will not work, because you are blocking the main thread during your lengthy thing and not letting UIKit actually start the spinner.
不会工作,因为你在冗长的事情中阻塞了主线程,而不是让 UIKit 真正启动微调器。
- (void) handleDoSomethingButton{
[mySpinner startAnimating];
dispatch_async (dispatch_get_main_queue(), ^{
(do something lengthy)
[mySpinner stopAnimating];
});
}
will return control to the run loop, which will schedule UI updating, starting the spinner, then will get the next thing off the dispatch queue, which is your actual processing. When your processing is done, the animation stop is called, and you return to the run loop, where the UI then gets updated with the stop.
将控制权返回给运行循环,该循环将安排 UI 更新,启动微调器,然后将下一个事件从调度队列中取出,这是您的实际处理。处理完成后,将调用动画停止,然后您返回到运行循环,然后 UI 会随着停止更新。
回答by Niall Kiddle
Swift 3, 4 & 5
斯威夫特 3、4 和 5
Running code on the main thread
在主线程上运行代码
DispatchQueue.main.async {
// Your code here
}
回答by Esqarrouth
Async means asynchronous and you should use that most of the time. You should never call sync on main thread cause it will lock up your UI until the task is completed. You Here is a better way to do this in Swift:
Async 意味着异步,您应该在大多数情况下使用它。你不应该在主线程上调用同步,因为它会锁定你的 UI,直到任务完成。You Here 是在 Swift 中执行此操作的更好方法:
runThisInMainThread { () -> Void in
// Run your code like this:
self.doStuff()
}
func runThisInMainThread(block: dispatch_block_t) {
dispatch_async(dispatch_get_main_queue(), block)
}
Its included as a standard function in my repo, check it out: https://github.com/goktugyil/EZSwiftExtensions
它作为标准函数包含在我的 repo 中,请查看:https: //github.com/goktugyil/EZSwiftExtensions