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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:25:44