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

Swift4协议与代理回调实现困惑,求解决方案及代码示例

用协议代理实现VCB回调VCA的完整示例

没问题,我来帮你搞定这个Swift 4里的代理回调问题,直接上可运行的代码示例,每一步都给你讲清楚~

第一步:定义回调协议

我们先创建一个协议,用来规范VCB需要通知VCA执行的操作。这个协议可以放在VCB的.swift文件顶部,或者单独的文件里,这里为了方便放在VCB里:

import UIKit

// 定义回调协议,继承AnyObject才能让代理用weak修饰
protocol VCBToVCADelegate: AnyObject {
    // 协议方法:通知VCA刷新表格
    func refreshTableView()
}

class VCB: UIViewController {
    // 定义代理属性,必须用weak避免循环引用(VCA持有VCB,若代理为strong会导致双向持有内存泄漏)
    weak var delegate: VCBToVCADelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        // 添加操作按钮
        let actionButton = UIButton(type: .system)
        actionButton.setTitle("返回并刷新列表", for: .normal)
        actionButton.addTarget(self, action: #selector(actionButtonTapped), for: .touchUpInside)
        actionButton.frame = CGRect(x: 80, y: 200, width: 250, height: 50)
        view.addSubview(actionButton)
    }
    
    @objc func actionButtonTapped() {
        // 1. 先调用代理方法,通知VCA刷新表格
        delegate?.refreshTableView()
        // 2. 再pop回VCA
        navigationController?.popViewController(animated: true)
    }
}

第二步:让VCA遵守协议并实现代理方法

接下来处理VCA的代码,让它遵守我们定义的协议,实现刷新逻辑,同时在跳转到VCB时设置代理:

import UIKit

class VCA: UIViewController, UITableViewDataSource, UITableViewDelegate, VCBToVCADelegate {
    
    let tableView = UITableView()
    // 模拟数据源,点击VCB按钮后可以修改这个数组测试刷新效果
    var dataList = ["第一条数据", "第二条数据", "第三条数据"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        title = "列表页面"
        
        // 配置tableView
        tableView.frame = view.bounds
        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "defaultCell")
        view.addSubview(tableView)
    }
    
    // MARK: - UITableView数据源方法
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "defaultCell", for: indexPath)
        cell.textLabel?.text = dataList[indexPath.row]
        return cell
    }
    
    // MARK: - UITableView代理方法(处理cell点击跳转)
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let vcB = VCB()
        // 关键步骤:设置VCB的代理为当前VCA
        vcB.delegate = self
        navigationController?.pushViewController(vcB, animated: true)
    }
    
    // MARK: - VCBToVCADelegate代理方法实现
    func refreshTableView() {
        // 这里可以更新数据源,比如新增一条数据
        dataList.append("新增数据\(dataList.count + 1)")
        // 刷新表格
        tableView.reloadData()
    }
}

你可能踩过的坑(划重点!)

  • 忘记设置代理:很多时候回调失败都是因为跳转到VCB时没写vcB.delegate = self,这一步绝对不能漏!
  • 代理没加weak:如果代理属性不用weak,VCA和VCB会互相持有,导致内存泄漏,甚至回调失效。Swift里类类型的代理必须继承AnyObject才能用weak修饰。
  • 协议方法未实现:如果协议方法不是可选的(没加@objc optional),一定要在VCA里实现,否则编译会报错。

这样操作下来,你点击VCA的cell跳转到VCB,再点击VCB的按钮,就会先刷新VCA的表格,然后自动返回VCA啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:37:58