GCD在主线程中执行任务
我有一个可能来自任何线程的回调。当我收到这个回调时,我想在主线程上执行某个任务。
我是否需要检查我是否已经在主线程上 - 或者在调用下面的代码之前不执行此检查是否会产生任何惩罚?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
I have a callback which might come from any thread. When I get this callback, then I would like to perform a certain task on the main thread.
Do I need to check whether I already am on the main thread - or is there any penalty by not performing this check before calling the code below?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,您不需要检查您是否已经在主线程上。通过将块分派到主队列,您只需安排该块在主线程上串行执行,这会在运行相应的运行循环时发生。
如果您已经在主线程上,则行为是相同的:该块被调度,并在主线程的运行循环运行时执行。
No, you do not need to check whether you’re already on the main thread. By dispatching the block to the main queue, you’re just scheduling the block to be executed serially on the main thread, which happens when the corresponding run loop is run.
If you already are on the main thread, the behaviour is the same: the block is scheduled, and executed when the run loop of the main thread is run.
对于上面描述的异步调度情况,您不需要检查您是否在主线程上。正如 Bvarious 所指出的,这将简单地排队等待在主线程上运行。
但是,如果您尝试使用
dispatch_sync()
执行上述操作,并且您的回调位于主线程上,那么您的应用程序将在此时发生死锁。我在我的回答这里描述了这一点< /a>,因为当我从-performSelectorOnMainThread:
移动一些代码时,这种行为让我感到惊讶。正如我在那里提到的,我创建了一个辅助函数:如果您所在的方法当前不在主线程上,它将在主线程上同步运行一个块,如果在主线程上,则仅内联执行该块。您可以使用如下语法来使用它:
For the asynchronous dispatch case you describe above, you shouldn't need to check if you're on the main thread. As Bavarious indicates, this will simply be queued up to be run on the main thread.
However, if you attempt to do the above using a
dispatch_sync()
and your callback is on the main thread, your application will deadlock at that point. I describe this in my answer here, because this behavior surprised me when moving some code from-performSelectorOnMainThread:
. As I mention there, I created a helper function:which will run a block synchronously on the main thread if the method you're in isn't currently on the main thread, and just executes the block inline if it is. You can employ syntax like the following to use this:
正如其他答案提到的,来自主线程的dispatch_async 没问题。
但是,根据您的用例,存在一个您可能会认为是缺点的副作用:由于该块被调度在队列上,因此直到控制权返回到运行循环时它才会执行,这将产生延迟的效果你的块的执行。
例如,
将打印出:
因此,如果您期望该块在外部 NSLog 之间执行,则dispatch_async 将无法帮助您。
As the other answers mentioned, dispatch_async from the main thread is fine.
However, depending on your use case, there is a side effect that you may consider a disadvantage: since the block is scheduled on a queue, it won't execute until control goes back to the run loop, which will have the effect of delaying your block's execution.
For example,
Will print out:
For this reason, if you were expecting the block to execute in-between the outer NSLog's, dispatch_async would not help you.
不,您不需要检查您是否在主线程中。以下是在 Swift 中执行此操作的方法:
它作为标准函数包含在我的存储库中,请查看:https:// /github.com/goktugyil/EZSwiftExtensions
No you don't need to check if you're in the main thread. Here is how you can do this in Swift:
Its included as a standard function in my repo, check it out: https://github.com/goktugyil/EZSwiftExtensions