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

iOS委托模式问题:从TableView跳转传数据时Delegate属性为nil的求助

解决iOS委托模式中Delegate属性为nil的问题

嘿,我帮你揪出问题啦!你这是踩了委托模式里一个很常见的新手坑,咱们一步步拆解原因和解决办法:

问题根源

你代码里的delegate一直为nil,核心原因是你设置委托的对象根本不是正在和用户交互的那个ViewController:

  • 在SecondController的viewDidLoad里,你新创建了一个ViewController实例,并且给这个新实例设置了delegate,但这个新对象和你之前显示TableView的那个ViewController完全是两个独立的实例!原来的ViewController的delegate属性依然是空的,所以当你点击Cell调用delegate?.updateProperties时,自然没有任何反应。
  • 另外,你试图通过IBOutlet的didSet来更新UI,但这些控件在viewDidLoad之前还没完成初始化,而且你的s1、s2、img初始值都是空的,即使赋值成功,didSet也没法正确更新界面。

修正方案

正确的逻辑应该是:在跳转到SecondController之前,把当前ViewController的delegate绑定到即将弹出的SecondController实例上,同时调整UI更新的时机。

1. 修正ViewController的didSelectRowAt方法

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    let storyboard = UIStoryboard(name: Constants.storyboardName, bundle: nil)
    let nextController = storyboard.instantiateViewController(
        withIdentifier: Constants.destinationController
    ) as! SecondController
    
    // 关键:把当前ViewController的delegate设置为即将弹出的SecondController
    self.delegate = nextController
    
    let data = arr[indexPath.row]
    // 现在调用delegate方法就能触发SecondController的实现了
    delegate?.updateProperties(data)
    
    present(nextController, animated: true, completion: nil)
}

2. 修正SecondController的代码

删掉viewDidLoad里新建ViewController的无效代码,直接在委托方法里更新UI:

import UIKit
class SecondController: UIViewController {
    @IBOutlet weak var picture: UIImageView!
    @IBOutlet weak var label11: UILabel!
    @IBOutlet weak var label22: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemRed
        // 移除这里新建ViewController的代码,完全不需要
    }
}

extension SecondController: SendDataDelegate {
    func updateProperties(_ data: CellData) {
        // 直接在这里更新UI,此时IBOutlet已经完成初始化
        label11.text = data.str1
        label22.text = data.str2
        picture.image = data.img
    }
}

3. 额外优化(避免循环引用)

为了防止内存泄漏,建议给委托协议加上class限制,并把delegate声明为弱引用:

// 修改协议定义
protocol SendDataDelegate: class {
    func updateProperties(_ data: CellData)
}

// 在ViewController里修改delegate的声明
weak var delegate: SendDataDelegate?

为什么这样改?

当你点击Cell时,先实例化SecondController,把它设置为当前ViewController的delegate,然后调用委托方法传递数据。此时SecondController的视图控件已经完成初始化准备,直接赋值就能正确显示数据,不会出现之前的nil问题啦。

内容的提问来源于stack exchange,提问作者Abanoub Ashraf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:32:35