能否dispatch_async中断调用任务

Can dispatch_async interrupt calling task

假设我将任务异步分派到队列:

{
    // we are on main queue

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
      print("task B")
    });

    print("task A")

    // some long running work

    print("task A")

    // some long running work

    print("task A")
    ...
}

在任何情况下,分派的任务都可以中断从中分派它的任务吗?换句话说,是否会在所有 "task A"-s 打印之前打印 "task B"?

task A
task B
task A
task A
...

否则 GCD 将保证:

task A
task A
task A
...
task B

如果将任务分派到调用 dispatch_async 的同一个队列,会有什么不同吗?

In other words, can it ever happen that "task B" gets printed before all "task A"-s are printed?

这并非不可能,我不会说这里的任何事情都是 保证。异步意味着您告诉运行时 "whenever, dude"(假设这就是您喜欢与运行时交谈的方式)。

如果 dispatch_async 与被调用的队列相同, 该队列是 串行 队列,那么你的最后一个场景 保证:在当前块完成之前,我们无法在该队列上启动一个新块。 (但是 DISPATCH_QUEUE_PRIORITY_DEFAULT 是 不是 串行队列。)

In other words, can it ever happen that "task B" gets printed before all "task A"-s are printed?

这绝对有可能发生。如果您异步调度到 (a) 不同的队列;或 (b) 并发队列(全局队列是并发队列),您明确要求它们 运行 并发

AB 日志消息的确切顺序是各种任务耗时的函数,队列的优先级是什么,等等。但是如果你想 B 直到完成所有 A 任务后才出现,那么您应该明确控制该行为(通知调度组、串行队列、屏障等的块)。

如果你告诉我们你想保证什么行为,我们可以告诉你怎么做。

如果你想被"B"打印出来毕竟As,你可以这样保证:

// we are on main queue

print("task A")

// some long running work

print("task A")

// some long running work

print("task A")
...

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
^{
  print("task B")
});

显然这没有意义,如果 A 是长跑者而 B 是短跑者。

抱歉,我觉得你有点不明白,GCD是干什么用的。也许你想告诉我们,你真正的具体场景是什么,你想在那个场景中完成什么。