Swift 6 迁移常见 crash: _dispatch_assert_queue_fail

我的 Github:github.com/RickeyBoy/R...

大量 iOS 内容欢迎大家关注~

最近在将公司项目迁移到 Swift 6 的过程中,解决了好几个相似的 crash。关键字如下

Swift 复制代码
    _dispatch_assert_queue_fail
    
    "%sBlock was %sexpected to execute on queue [%s (%p)]
    
    Task 208: EXC_BREAKPOINT (code=1, subcode=0x103546f18)

在这里记录和分享,希望遇到相似的问题之后能够更快的解决。

Crash 1 信息

原因与解决 1

首先根据 crash 的提示,可以清楚地知道:Block 预期在一个线程上执行,而实际在另一个线程上执行。第一反应:大概率是主线程 vs 后台线程之间的不一致导致的。

如果经常熟练处理 Swift 6 升级的小伙伴就知道,一定是有地方标记了 @MainActor,也就意味着相对应的方法一定是要在主线程上执行的;而实际阴差阳错,在后台线程执行了。

所以接下来可能需要找,到底哪里线程不一致呢?我们根据代码来寻找即可。

不难找到,根据 Combine 调用链,可以发现其中一处对于 userPublisher 的监听时,选择了在 global 上去执行后面的操作,所以这里需要将这一个逻辑去掉。

于此同时,对于 userPublisher 的发布,我们也最好将其默认放在主线程上,因为他是和 UI 相关的,所以需要做这样的改动:

坑点

目前是不是觉得好像这个类型的 crash 不算很难解决?没错,这个 crash 的提示相对清楚,知道大概原因后去找就相对容易了。

不过需要注意的是,当使用 Combine 框架遇上这类型的 crash 时,crash 断点只会发生在 Publisher 而不是 Observer 处,所以我们需要自己去寻找调用方,看下在哪里出现了线程使用不一致的问题。

Crash 2 信息

好的,那么同类型的一个 crash 再来看看:

报错信息就不贴了,和上一个 crash 是一样的,都是:"%sBlock was %sexpected to execute on queue [%s (%p)]

这里可以看到,crash 断点处在子线程,也是在 AsyncStream 发布处断点。那么根据经验推断,可以大概知道原因:

  1. 此处发布的时候,处在子线程
  2. 下游调用方,一定有某个地方要求在主线程
  3. 实际线程与要求线程不一致,所以导致 crash

原因与解决 2

这里寻找过程就不赘述了。原来的发布者是处在子线程,而后面的监听者处在主线程,因此需要改在主线程发布。

相关推荐
人月神话-Lee21 小时前
WWDC26 深度解析:如何在 iOS 27 中打造“秒开”的相机体验
ios·swift·相机·wwdc·用户体验
Tr2e1 天前
🐱 从 0 到 1:用 Swift 手搓一个 macOS 桌面宠物(附源码)
macos·ios·swift
人月神话-Lee2 天前
【WWDC】Core AI:iOS 端侧大模型新纪元
人工智能·ios·ai·swift·wwdc·core ai
2501_916007472 天前
iOS 开发工具选择指南 从编辑器、编译器到自动化构建
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
Fatbobman(东坡肘子)2 天前
WWDC 2026 初印象:符合预期,但更务实 -- 肘子的 Swift 周报 #139
人工智能·macos·ios·swiftui·swift·wwdc
大熊猫侯佩3 天前
WWDC26 全网首发:SwiftUI 8 “可重排序“操作符深度解析
ios·swiftui·swift
人月神话-Lee3 天前
【图像处理】颜色空间——RGB之外的世界
图像处理·人工智能·ios·ai编程·swift·rgb·颜色空间
东坡肘子3 天前
WWDC 2026 初印象:符合预期,但更务实 -- 肘子的 Swift 周报 #139
人工智能·swiftui·swift
大熊猫侯佩3 天前
WWDC26 前瞻:苹果可能放出的“王炸”,不只是 Siri
xcode·swift·wwdc