for (int i = 0; i < 20; i++) {
dispatch_async(queue, ^{
NSLog(@"xxx");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"yyy");
});
});
}
希望打印 "xxx"、"yyy"、"xxx"、"yyy"...。
如何修改?
你有几个问题。
首先,你使用的是 dispatch_async()
. 该函数将一组代码排队执行。异步 在其他线程上。
这有两个重要的含义。
queue
是一个 并发 队列(默认),那么其他19个块也可以同时执行;事实上,所有20个块可能同时运行,但不保证顺序。为了保证打印 "xxx"、"yyy"、"xxx"、"yyy"、......,必须确保初始块都执行 依次,并且每个子块执行 同步.
所以你的代码需要像这样。
// `queue` must be created as a serial queue
dispatch_queue_t queue = dispatch_queue_create("xxxs",DISPATCH_QUEUE_SERIAL);
for (int i = 0; i < 20; i++) {
dispatch_async(queue, ^{
NSLog(@"xxx");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"yyy");
});
});
}
循环会立即创建20个代码块并排队,将它们添加到序列号中。queue
顺序。因为 queue
是串行的,队列中每次只执行一个块,第二个队列中的块要等到第一个块完成后才会开始。
当第一个代码块执行完毕后,它打印 "xxx",然后是 同步 排队在主线程上运行一个块。同步调用使线程(第一个块)停止运行,直到该子块在主线程上执行完毕。
一旦 "yyy "块执行完毕,就会有 dispatch_sync
调用返回,第一个代码块恢复执行并退出。第二个代码块在 queue
开始运行,整个过程重复进行,直到所有的块都执行完毕。
说了这么多,因为你想让所有这些代码都按顺序执行,所以创建一个串行队列并添加单个块并没有什么好处。这段代码做的事情是完全一样的,而且更简单。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
for (int i = 0; i < 20; i++) {
NSLog(@"xxx");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"yyy");
});
}
});
我希望这能帮助你理解队列和同步与异步调度调用。