You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将BlockOperation加入OperationQueue后为何后续代码会继续执行?

Operation加入队列后不阻塞后续代码的原因

首先要明确两个容易混淆的核心概念,"Operation默认同步执行"的结论存在适用前提:

  • Operation默认同步执行的成立场景是手动调用start()方法启动操作:同步操作不会自行创建新线程,调用start()的当前线程会阻塞,等待操作的任务逻辑全部执行完毕后,才会继续运行start()之后的代码。
  • OperationQueue是独立的任务调度器,默认工作在并发模式:你调用addOperation(_:)提交任务时,方法会立刻返回,不会等待任务执行完成。队列会自行管理线程池,把提交的操作分配到非当前调用线程的其他线程上启动执行,根本不会阻塞当前代码所在的线程。

对应的测试代码如下:

let op = BlockOperation(block: { print("Done") })
let qu = OperationQueue()
qu.addOperation(op)
print("after!")

实际运行输出顺序为:

after!
Done

出现这个执行顺序的具体逻辑:

  1. 示例中创建的BlockOperation确实是默认的同步操作,它的isAsynchronous属性默认返回false,但这个属性仅在手动启动操作时生效,用来标识操作是否会自己管理生命周期、异步执行,对加入队列的操作来说,这个标记不会影响队列的调度逻辑。
  2. 当代码运行在主线程时,调用qu.addOperation(op)只是把操作提交到队列的待调度列表,队列会取出可用的后台线程,在后台线程上调用操作的start()方法执行block。这个过程完全不占用主线程的执行时间,所以主线程会立刻继续往下走,先执行print("after!")。等后台线程调度到这个操作时,才会执行block打印"Done"。

如果要验证同步操作的特性,可以把提交队列的代码换成直接手动启动操作:

let op = BlockOperation(block: { print("Done") })
op.start() // 手动在当前线程启动同步操作
print("after!")

这时输出顺序就会变成先打印"Done",再打印"after!",符合同步操作阻塞当前调用线程的特性。

内容的提问来源于stack exchange,提问作者daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:45:44