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

Cocoa Swift 用protocol与delegate在两个ViewController间回传数据失败怎么办

问题根因
  • 从FirstViewController跳转至SecondViewController时,未给新创建的SecondViewController实例的delegate属性赋值,代理默认值为nil,后续回调逻辑无法触发
  • SecondViewController点击返回按钮时,先执行了页面跳转再调用代理方法,跳转后当前Second实例可能被释放,weak修饰的delegate会自动置空,同时你重新实例化了一个全新的FirstViewController,和之前跳转前的First实例不是同一个对象,就算回调触发也不会修改原有页面的UI
修正代码

FirstViewController.swift

//  FirstViewController.swift
import Cocoa

class FirstViewController: NSViewController, DataEnteredDelegate {
    @IBOutlet weak var buttonPasswordState: NSView!
    @IBOutlet weak var label: NSTextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func buttonPasswordState(_ sender: Any) {
        guard let controller = self.storyboard?.instantiateController(withIdentifier: "SecondViewController") as? SecondViewController else { return }
        // 给SecondViewController的代理赋值为当前First实例
        controller.delegate = self
        self.view.window?.contentViewController = controller
    }
    
    func userDidEnterInformation(info: String) {
        label.stringValue = info
        // 可添加日志确认回调触发
        print("接收到回传数据: \(info)")
    }
}

SecondViewController.swift

//  SecondViewController.swift
import Cocoa

protocol DataEnteredDelegate: class {
    func userDidEnterInformation(info: String)
}

class SecondViewController: NSViewController {
    @IBOutlet weak var buttonContinue: NSButton!
    weak var delegate: DataEnteredDelegate? = nil
    @IBOutlet weak var textField: NSTextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func buttonContinue(_ sender: Any) {
        // 先执行代理回调传递数据,再执行页面跳转
        delegate?.userDidEnterInformation(info: textField.stringValue)
        // 不需要重新实例化FirstViewController,直接切换回原有页面即可,若为模态弹出场景可直接调用dismiss
        guard let controller = self.storyboard?.instantiateController(withIdentifier: "FirstViewController") as? FirstViewController else { return }
        self.view.window?.contentViewController = controller
    }
}
调试提示

可在代理调用位置和代理实现位置增加打印日志,若调用代理前打印delegate值为nil,说明跳转前的代理赋值逻辑未生效,可检查Storyboard中ViewController的Identifier是否正确配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:15:00