Swift开发:如何在prepare(for segue:)方法中传递已捕获的错误?
完全没必要把错误信息存成类属性,利用performSegue原生支持的sender参数就能直接传递捕获的错误,全程不需要额外的临时存储,是最简便的实现方式。
实现逻辑
performSegue的sender参数本来就是设计用来给对应触发的转场传递临时上下文数据的,你只需要在捕获到错误的位置,把错误信息打包直接传给sender,再在prepare(for:)里从sender取出数据赋值给目标控制器就行。
改造后的代码
- 捕获错误的环节,直接把错误信息作为sender传入segue:
override func viewDidAppear(_ animated: Bool) { do { try CheckAndCopyDatabase(filename: "test.db") // 校验通过后再触发正常流程的转场 performSegue(withIdentifier: "segueStartup2Begin", sender: self) } catch ApplicationError.configurationError(let errorMsg, let errorMsgDetail) { // 直接把错误信息打包成元组传给sender,不额外定义类属性 performSegue( withIdentifier: "segueStartup2Exit", sender: (errorMsg, errorMsgDetail) ) } catch { // 其他兜底错误的处理逻辑 } }
这里要修正你原代码的一个逻辑漏洞:你原来把
segueStartup2Begin的触发放在了catch块外面,会导致校验失败时连续触发两个转场,出现动画冲突甚至运行时警告,一定要把正常流程的转场挪到校验通过的分支里执行。
- 在
prepare(for:)环节从sender中取出错误信息赋值给目标控制器:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // 直接匹配转场ID判断即可,不需要特意判断自定义Segue子类类型 if segue.identifier == "segueStartup2Exit", let targetVC = segue.destination as? ViewControllerExit, let errorInfo = sender as? (String, String) { targetVC.errorMsg = errorInfo.0 targetVC.errorMsgDetail = errorInfo.1 } }
更稳妥的类型优化
如果觉得松散的元组在取参数时容易搞混顺序,可以定义一个轻量的上下文结构体来承载错误信息,编译期就能做类型校验,后续维护也不容易出错:
// 承载启动阶段的错误转场上下文 struct StartupErrorContext { let message: String let detail: String }
传参和取参的时候直接用这个类型替换元组即可,整体逻辑完全一致。
和存类属性的方案比,这种方式的优势很实际:
- 不会在当前控制器上残留多余的临时属性,避免多个转场场景下临时属性被覆盖的时序问题
- 错误信息的传递链路是完全顺向的,从捕获到使用的逻辑闭环很短,不需要跨作用域读取类成员
- 代码耦合度低,不会因为临时属性的存在导致后续维护时出现逻辑遗漏
内容的提问来源于stack exchange,提问作者frameworker
相关产品推荐
相关产品推荐

