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

Swift:如何在两个ViewController间推送通知并传递函数执行结果?

嘿,我来帮你搞定这个跨ViewController的通知调用问题!在Swift开发里,这种场景其实挺常见的,我给你两种靠谱的解决方案,你可以根据自己的需求选:

方案一:用NotificationCenter实现触发调用(适合单向触发)

这是最经典的跨组件通知方式,适合只需要触发第一个VC的函数,不需要返回值给第二个VC的场景(当然第一个VC里可以自己打印结果)。

1. 在第一个ViewController中注册通知

首先我们要给第一个VC注册自定义通知,同时记得在销毁时移除观察者,避免内存泄漏:

class FirstViewController: UIViewController {
    // 定义全局唯一的通知名称,建议用extension统一管理,避免拼写错
    static let callFirstVCFunctionNotification = Notification.Name("CallFirstVCFunction")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 注册通知,绑定要执行的指定函数
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(runSpecifiedFunction),
            name: FirstViewController.callFirstVCFunctionNotification,
            object: nil
        )
    }
    
    deinit {
        // 页面销毁时移除观察者,防止内存泄漏
        NotificationCenter.default.removeObserver(self)
    }
    
    // 你需要被调用的指定函数,要加@objc让NotificationCenter能识别
    @objc func runSpecifiedFunction() {
        let executionResult = "第一个VC的指定函数执行完成!"
        print(executionResult)
        // 如果需要把结果传给第二个VC,可以通过通知的userInfo传递,后面会说
    }
}

2. 在第二个ViewController中发送通知

当你需要触发第一个VC的函数时,直接发送我们定义的通知就行:

class SecondViewController: UIViewController {
    // 比如在按钮点击事件里触发
    @IBAction func triggerFirstVCFunction(_ sender: UIButton) {
        NotificationCenter.default.post(
            name: FirstViewController.callFirstVCFunctionNotification,
            object: nil
        )
    }
}

如果需要第一个VC把执行结果回传给第二个VC,那可以修改通知的userInfo:

// 第一个VC的函数里修改
@objc func runSpecifiedFunction() {
    let executionResult = "第一个VC的指定函数执行完成!"
    print(executionResult)
    // 先新增一个结果通知的名称
    static let resultReturnNotification = Notification.Name("FirstVCFunctionResult")
    // 把结果通过userInfo传递回去
    NotificationCenter.default.post(
        name: FirstViewController.resultReturnNotification,
        object: nil,
        userInfo: ["result": executionResult]
    )
}

// 第二个VC里注册这个结果通知
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(receiveFunctionResult(_:)),
        name: FirstViewController.resultReturnNotification,
        object: nil
    )
}

@objc func receiveFunctionResult(_ notification: Notification) {
    if let result = notification.userInfo?["result"] as? String {
        print("第二个VC收到的执行结果:\(result)")
    }
}
方案二:用闭包实现(适合需要双向传递数据的场景)

如果你的需求是第二个VC要直接拿到第一个VC函数的执行结果,用闭包会比通知更直接,因为通知是单向通信,闭包可以直接回调获取值。

1. 在第二个ViewController中定义闭包属性

class SecondViewController: UIViewController {
    // 定义闭包,用来触发第一个VC的函数并接收返回值
    var getFirstVCFunctionResult: (() -> String?)?
    
    @IBAction func triggerFirstVCFunction(_ sender: UIButton) {
        // 调用闭包,获取第一个VC函数的结果并打印
        if let result = getFirstVCFunctionResult?() {
            print("第二个VC收到的执行结果:\(result)")
        }
    }
}

2. 在第一个ViewController跳转时绑定闭包

当你从第一个VC跳转到第二个VC时,把闭包指向你要执行的指定函数:

class FirstViewController: UIViewController {
    // 跳转逻辑,比如按钮点击或者其他触发时机
    func goToSecondVC() {
        let secondVC = SecondViewController()
        // 绑定闭包,注意用[weak self]避免循环引用
        secondVC.getFirstVCFunctionResult = { [weak self] in
            guard let self = self else { return nil }
            return self.runSpecifiedFunction()
        }
        navigationController?.pushViewController(secondVC, animated: true)
    }
    
    // 你的指定函数,不需要加@objc了
    func runSpecifiedFunction() -> String {
        let executionResult = "第一个VC的指定函数执行完成!"
        print(executionResult)
        return executionResult
    }
}

关键注意点

  • 用NotificationCenter时,一定要在deinit里移除观察者,不然会导致内存泄漏,VC无法被释放。
  • 用闭包时,必须用[weak self]或者[unowned self]避免循环引用,尤其是两个VC通过导航栈关联的时候,很容易出现循环引用的问题。
  • 通知名称最好用extension Notification.Name来统一管理,比如:
extension Notification.Name {
    static let callFirstVCFunction = Notification.Name("CallFirstVCFunction")
    static let firstVCFunctionResult = Notification.Name("FirstVCFunctionResult")
}

这样可以避免拼写错误,代码也更整洁。

两种方案都能实现你要的效果,如果你只需要触发第一个VC的函数并让它自己打印结果,方案一足够;如果第二个VC需要拿到结果,方案二更直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:09:22