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

Swift Error转NSError在macOS 10.13上崩溃,如何解决?

解决macOS 10.13下Swift Error转NSError过早释放的崩溃问题

解决方案1:延长NSError的生命周期

可以通过withExtendedLifetime函数强制让NSError实例在指定代码块内保持存活,避免提前释放:

enum TestError: Error {
    case test
}

func test() {
    let error = TestError.test
    print(error)
    
    let capturedError: NSError = error as NSError
    withExtendedLifetime(capturedError) {
        if let urlError = capturedError as? URLError {
            print("error is URLError")
        }
    }
    print("Finished")
}

或者手动添加一个强引用变量来持有NSError:

func test() {
    let error = TestError.test
    print(error)
    
    let capturedError: NSError = error as NSError
    let keepAlive = capturedError // 额外强引用延长生命周期
    if let urlError = capturedError as? URLError {
        print("error is URLError")
    }
    print("Finished")
}

解决方案2:跳过不必要的双重转换

你不需要先将自定义Error转为NSError再判断是否为URLError,直接对原始Error实例做类型检查即可,从根源上避免触发内存管理bug:

func test() {
    let error = TestError.test
    print(error)
    
    if let urlError = error as? URLError {
        print("error is URLError")
    }
    print("Finished")
}

问题根源

macOS 10.13及更早版本的Swift Runtime在处理Swift Error到NSError的转换时存在内存管理缺陷:转换生成的NSError实例引用计数管理异常,导致后续对该实例做类型转换时,它可能已经被提前释放。你的代码中的双重转换(Error→NSError→URLError)刚好触发了这个旧系统上的bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:38:13