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
相关产品推荐
相关产品推荐

