Swift iOS中使用闭包回传数据遇nil错误求助
问题原因分析
你代码里的核心错误是:在FormsVC的btnOk_Event中新建了一个全新的ProfileVC实例,这个实例的界面控件(包括lblFavouritePet)还没有完成视图加载流程,处于nil状态,调用setPetName时自然会触发隐式解包崩溃。而且你需要回传数据的是原来弹出FormsVC的那个ProfileVC实例,不是新建的。
正确的闭包实现步骤
按照闭包传值的逻辑,我们需要让FormsVC持有一个闭包,在选中宠物并点击OK时,调用闭包把数据传递给原来的ProfileVC。
1. 修改FormsVC代码
添加闭包属性
在FormsVC的变量声明部分,新增一个闭包属性,用于传递选中的宠物名称:
// FormsVC // MARK: - Variable Declaration var favoritePet = String() // 新增:用于回传选中宠物的闭包 var onPetSelected: ((String) -> Void)?
优化按钮标题设置(可选但推荐)
原来的setUpFormsVC直接修改titleLabel?.text可能会失效,应该用UIButton的标准方法设置标题:
func setUpFormsVC() { btnDog.setTitle("Dog", for: .normal) btnCat.setTitle("Cat", for: .normal) btnRabbit.setTitle("Rabbit", for: .normal) btnBird.setTitle("Bird", for: .normal) }
修改OK按钮的事件处理
删除新建ProfileVC的代码,改为调用闭包传递数据后关闭当前VC:
@IBAction func btnOk_Event(_ sender: UIButton) { // 确保选中的宠物名称不为空,默认值设为Dog let selectedPet = favoritePet.isEmpty ? "Dog" : favoritePet // 调用闭包,把选中的宠物名称传回去 onPetSelected?(selectedPet) // 关闭FormsVC self.dismiss(animated: true, completion: nil) }
2. 修改ProfileVC代码
在弹出FormsVC时,给FormsVC的闭包赋值,在闭包里更新当前ProfileVC的标签:
@IBAction func btnSelectYourFavPet_Event(_ sender: UIButton) { let vc = FormsVC() // 设置闭包,接收回传的宠物名称并更新UI // 用[weak self]避免循环引用 vc.onPetSelected = { [weak self] petName in self?.lblFavouritePet.text = petName } self.present(vc, animated: true) }
3. 移除冗余代码
可以删除ProfileVC里的setPetName方法,以及FormsVC里的getFavoritePet方法,因为闭包传值已经不需要这些间接调用了。
这样修改后,当你在FormsVC选中宠物并点击OK,数据会通过闭包传递给原来的ProfileVC,直接更新标签,不会再出现nil崩溃的问题。
内容的提问来源于stack exchange,提问作者SwiftNewbie
相关产品推荐
相关产品推荐

