为什么使用Combine的catch算子会触发segmentation fault错误?
问题成因
这个问题是Xcode 13.0/13.1内置的Swift 5.5编译器在Release模式高优化等级下的已知bug,触发原因和Combine catch算子的泛型类型推导优化逻辑缺陷相关,具体如下:
- 你的业务代码本身不存在语法或逻辑错误,Debug模式下编译器优化等级低、类型推导逻辑更保守,因此不会触发异常;Release模式默认开启高等级优化(
-O/-O3),编译器会执行函数内联、泛型类型擦除简化、自动类型推断合并等操作,此时触发了编译器内部的内存访问错误,也就是你遇到的segmentation fault 11。 - 具体触发位置是
catch闭包的返回类型推导阶段:上游fetchValue经过map转换后输出类型为State,catch闭包返回的Just发布者输出类型也为State,Swift 5.5编译器的类型检查器在优化阶段验证两个类型一致性时出现野指针访问,直接导致编译器崩溃。
临时修复方案
你可以通过显式标注catch闭包的返回类型绕过这个编译器bug,修改后的代码如下:
fetchValue .map(State.someValue) .catch { error -> Just<State> in // 增加显式返回类型标注 Just(State.error(error.localizedDescription)) } .receive(on: scheduler) .assign(to: \.state, on: self) .store(in: &subscriptions)
也可以将Just替换为Result.Publisher避免触发该问题,或者直接升级到Xcode 13.2及以上版本,该版本已经修复了这个编译器缺陷。
内容的提问来源于stack exchange,提问作者Fogmeister
相关产品推荐
相关产品推荐

