确保我正确解释了嵌套 GCD

Making sure I'm explaining nested GCD correctly

所以我使用 dispatch_async 将 10 个任务放在 并发队列 上。它们不会阻塞下一个任务,并按顺序进行处理。我的 UI 反应灵敏。

for (int i = 0; i < 10; i++) {

    dispatch_async(concurrencyQueue, ^() {

        NSLog(@"..calling insertion method to insert record %d", i);

           dispatch_sync(serialQueue, ^() {

            //this is to simulate writing to database
            NSLog(@"----------START %d---------", i);
            [NSThread sleepForTimeInterval:1.0f];
            NSLog(@"--------FINISHED %d--------", i);

        });

    });
}

在每个任务中,我们通过 dispatch_sync[=31 在 串行队列 上模拟以“1 秒睡眠”写入数据库=].

我一直认为 dispatch_sync 会阻止所有人,并同步其任务,因为这就是我单独使用它时的行为方式。但是,在这种情况下,它不会阻塞主线程。相反,它像我想要的那样在后台漂亮地运行。

是否因为与队列关联的线程受到影响?

例如,主线程正在通过dispatch_async执行并发队列,这就是它没有被阻塞的原因。

dispatch_sync 仅针对在并发队列上工作的后台线程进行同步和阻塞。因此,dispatch_sync 与后台线程相关联,因此不会影响我的 UI 主线程。

我的想法正确吗?

谢谢!

是的,你是对的。 dispatch_sync() 仅阻塞队列 运行 所在的线程。

您永远不会阻塞主线程,因为您的代码在 concurrencyQueue 的线程或 serialQueue 的线程上 运行。 None 其中是主线程。

sleep 的所有调用都在 serialQueue 的线程上一一发生。所以阻塞的是serialQueue的线程。

但是,由于您使用 dispatch_sync 分派到 serialQueue,您还阻塞了并发队列的每个线程。如果在调用 dispatch_sync.

之后再添加一个 NSLog ,效果会更好
for (int i = 0; i < 10; i++) {
    dispatch_async(concurrencyQueue, ^() {
        NSLog(@"..calling insertion method to insert record %d", i);

        dispatch_sync(serialQueue, ^() {
            //this is to simulate writing to database
            NSLog(@"----------START %d---------", i);
            [NSThread sleepForTimeInterval:1.0f];
            NSLog(@"--------FINISHED %d--------", i);
        });

        NSLog(@"..called insertion method to insert record %d", i);
    });
}

dispatch_sync 之后的第二个 NSLog 将更好地向您展示 dispatch_sync 如何影响对 dispatch_async.

的调用