问题描述
这可能是一个愚蠢的问题,但我需要自己询问并清除它。
It may be a dumb question but I need to ask and clear this up for myself.
要将一个块提交到队列中执行,请使用函数 dispatch_sync
和 dispatch_async
。它们都将队列和块作为参数。 dispatch_async
立即返回,异步运行块,而 dispatch_sync
阻止执行,直到提供的块返回。以下是一些情况:
To submit a block onto a queue for execution, use the functions dispatch_sync
and dispatch_async
. They both take a queue and a block as parameters. dispatch_async
returns immediately, running the block asynchronously, while dispatch_sync
blocks execution until the provided block returns. Here are some situations:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_async(queue, ^{
NSLog(@"this is statement1");
});
});
情况2
Situation 2
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_sync(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_sync(queue, ^{
NSLog(@"this is statement1");
});
});
情况3
Situation 3
{
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_sync(queue, ^{
NSLog(@"this is statement1");
});
});
情况4
Situation 4
{
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_sync(queue, ^{
[self goDoSomethingLongAndInvolved];
dispatch_async(queue, ^{
NSLog(@"this is statement1");
});
});
}
和 goDoSomethingLongAndInvolved
是
-(void)goDoSomethingLongAndInvolved {
NSLog(@"goDoSomethingLongAndInvolved");
}
我试图在Xcode中运行它们但我看不出它们的区别。
I tried to run them in Xcode but I cant see the difference at all.
所以我的问题是:
- 这些情况之间的主要区别是什么?
- 如果我用
dispatch_get_main_queue()
替换queue
怎么办?
- What's the main difference between these situations?
- What if I replace
queue
withdispatch_get_main_queue()
?
推荐答案
dispatch_sync
语句一直等到块它涵盖了完全执行。 dispatch_async
立即返回并继续执行下一行代码,因此内部的所有内容都是并行发生的。
The dispatch_sync
statement waits until the block it covers is executed completely. dispatch_async
returns immediately and proceeds to the next line of code, so everything inside is happening in parallel.
如果 queue
是您自己创建的串行队列,那么:
If queue
was a serial queue created by yourself, then:
情况1 - 根块立即返回。在里面它等待[self go ....],然后转到dispatch_async,它也会立即返回。
Situation 1 - The root block returns immediately. Inside it waits for [self go....], and then goes to dispatch_async, which returns immediately as well.
情况2 - 如果 queue
是一个串行队列,然后会有一个死锁,因为它会等待自己完成执行。由于您正在处理异步,因此该块将并行执行。 (谢谢,@ Ken Thomases)
Situation 2 - If queue
was a serial queue, then there would be a dead lock since it will wait for itself to finish executing. Since you are dealing with asynchronous one, that block will be executed in parallel. (Thanks, @Ken Thomases)
情况3 - 此处不需要 dispatch_sync
。它导致死锁。
Situation 3 - No need in dispatch_sync
here. It causes the deadlock.
情况4 - 等待[self ...],然后立即返回。
Situation 4 - Waits for [self ...], then returns immediately.
如果用主队列替换队列
,请记住不要 dispatch_sync
在主队列上,因为它会导致死锁(如果不是从主线程调度则不会,感谢@Ken Thomases)。
If you replace the queue
with main queue, then remember to not dispatch_sync
on main queue, because it will cause a deadlock (it will not if dispatched not from main thread, thanks @Ken Thomases).
为了更好地理解它,请用以下代码替换你的函数:
To understand it better, replace your function with:
-(void)goDoSomethingLongAndInvolved:(NSString *)message {
for(int i = 0; i < 50; ++i) {
NSLog(@"%@ -> %d", message, i);
}
}
你会清楚地看到每次发生的事情,无论是它等待与否。祝你好运。
You will clearly see what's going on every time, whether it waits or not. Good luck.
这篇关于如果我嵌套了dispatch_async调用,会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!