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

Swift:Segue跳转后无法修改Model变量及代理方法未调用问题

问题分析与解决

一、直接赋值变量返回后无变化的原因

你在MenuTableViewController里声明了private let gameBrain = GameBrain(),这是创建了一个全新的GameBrain实例,和ViewController中使用的GameBrain不是同一个对象。所以你修改这个局部实例的变量,只会影响当前页面的这个实例,返回ViewController后,原来的实例完全没被改动。

二、代理方法未执行的核心问题

你的代理方法没被调用,本质是MenuTableViewController的delegate属性是nil,没有被赋值给任何对象:

  • 你虽然让GameBrain遵守了MenuTableViewControllerDelegate协议,但没有把正确的GameBrain实例(也就是ViewController中使用的那个)赋值给MenuTableViewController的delegate属性。
  • 就算你想让TableVC里的局部gameBrain当代理,也没写self.delegate = gameBrain,所以delegate始终是nil,调用delegate?.resetPlayerScore()时会直接忽略。

三、正确的实现步骤

步骤1:传递共享的GameBrain实例

在ViewController处理Segue跳转时,把自身持有的GameBrain实例传递给TableVC,同时设置代理:

// 在ViewController中重写prepare方法
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let menuVC = segue.destination as? MenuTableViewController {
        // 假设ViewController里有一个名为gameBrain的属性,是当前使用的实例
        menuVC.gameBrain = self.gameBrain
        menuVC.delegate = self.gameBrain
    }
}

同时修改MenuTableViewController的代码,去掉局部实例声明,改为接收外部传递的对象:

class MenuTableViewController: UITableViewController {
    weak var delegate: MenuTableViewControllerDelegate?
    // 改为可选变量,接收外部传递的GameBrain实例
    var gameBrain: GameBrain?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        switch indexPath.row {
        case 0:
            delegate?.resetPlayerScore()
        default:
            break
        }
    }
}

步骤2:完善代理方法的功能

在GameBrain的代理扩展中,添加实际的重置逻辑:

extension GameBrain: MenuTableViewControllerDelegate {
    func resetPlayerScore() {
        print("IT WORKS!")
        // 这里添加你的分数重置逻辑,比如:
        // self.playerScore = 0
    }
}

步骤3:确保代理对象的生命周期

因为delegate用weak修饰,只要你的GameBrain实例被ViewController(或其他持有强引用的对象)保留,就不会被提前释放,代理调用就能正常执行。

四、简化方案:跳过代理直接修改

如果逻辑简单,也可以不用代理,直接在TableVC的选中事件里修改传递过来的GameBrain实例:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    
    switch indexPath.row {
    case 0:
        gameBrain?.playerScore = 0
        print("分数已重置")
    default:
        break
    }
}

内容的提问来源于stack exchange,提问作者dvd.trsnk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:15:59