通过Protocol&Extension在MainScreenVC与RatesVC间传值崩溃求助
问题分析与解决方案
看起来你遇到的崩溃和数据传递失败,主要是两个关键问题导致的:
1. 协议参数类型不匹配+不安全传递
你的transferNameOfCurrency协议要求方法参数是String类型,但在MainScreenVC里,你直接传递了可选类型String?的nameOfTheCurrency。虽然你手动赋值为"EUR",但如果这个值意外为nil,直接传递会触发崩溃;而且严格来说这属于类型不匹配,编译器其实应该给你报错才对。
2. Delegate绑定到了错误的实例
在RatesVC的viewDidLoad里,你实例化了一个全新的MainScreenVC对象,然后给这个新对象设置delegate。但这个新对象根本不是你界面上实际显示的那个MainScreenVC!真正显示的MainScreenVC的transferCurrencyDelegate仍然是nil,所以当你调用transferCurrencyDelegate?.currencySelected(...)时,不仅回调不会触发,还可能因为参数类型问题直接崩溃。
修正后的完整代码
第一步:修复MainScreenVC的参数传递
import UIKit // 建议规范协议命名,加上AnyObject限制类遵守,避免循环引用 protocol CurrencyTransferDelegate: AnyObject { func currencySelected(nameOfCurrency: String) } class MainScreenVC: UIViewController { // 用weak修饰delegate,防止内存泄漏 weak var transferCurrencyDelegate: CurrencyTransferDelegate? var nameOfTheCurrency: String? @IBAction func updateRates(_ sender: Any) { nameOfTheCurrency = "EUR" // 安全解包后再传递参数,避免nil崩溃 if let currencyName = nameOfTheCurrency { transferCurrencyDelegate?.currencySelected(nameOfCurrency: currencyName) } print(nameOfTheCurrency ?? "未获取到货币名称") } }
第二步:正确绑定Delegate到实际显示的MainScreenVC
假设你的导航流程是从RatesVC跳转到MainScreenVC,那么在跳转时给实际要显示的MainScreenVC设置delegate,而不是在viewDidLoad里实例化新对象:
import UIKit class RatesVC: UIViewController { var currencySelected: String? override func viewDidLoad() { super.viewDidLoad() // 删除原来错误的实例化代码,保留必要的初始化逻辑 } // 示例:处理跳转到MainScreenVC的按钮点击事件 @IBAction func navigateToMainScreen(_ sender: Any) { if let mainVC = storyboard?.instantiateViewController(withIdentifier: "MainScreenVC") as? MainScreenVC { // 给即将显示的MainScreenVC设置delegate为当前RatesVC实例 mainVC.transferCurrencyDelegate = self navigationController?.pushViewController(mainVC, animated: true) } } } extension RatesVC: CurrencyTransferDelegate { func currencySelected(nameOfCurrency: String) { currencySelected = nameOfCurrency print("收到传递的货币名称:\(currencySelected ?? "nil")") } }
为什么这样能解决问题?
- 安全的参数传递:用可选绑定确保传递的是确定的
String类型,避免了nil导致的崩溃; - 正确的Delegate绑定:给实际要显示的
MainScreenVC实例设置delegate,确保当updateRates触发时,RatesVC能收到回调并获取数据; - 内存安全:给delegate加上
weak修饰符,避免了两个VC互相引用导致的内存泄漏问题。
内容的提问来源于stack exchange,提问作者Ula
相关产品推荐
相关产品推荐

