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

UITableView中Delegate Method未触发及数据传递异常问题

iOS数据传递问题排查与修复

问题

尝试从ViewController向UITableViewCell传递数据时遇到两个问题:

  • 自定义代理方法getDeviceData未被调用
  • UITableViewCell内CollectionView的numberOfItemsInSection方法中deviceArray为nil,但didSelectItemAt方法中deviceArray能正常获取数据

相关代码

ViewController代码

protocol homeVCdelegate {
    func getDeviceData(_ controller : HomeViewController, deviceData : [device])
}

// 注册UITableView
shortcutTable.delegate = self
shortcutTable.dataSource = self
shortcutTable.register(UINib(nibName: "shortcutCell", bundle: nil), forCellReuseIdentifier: "shortcutCell")

// 声明代理
var delegate : homeVCdelegate?

// API请求内调用代理方法
DispatchQueue.main.async {
    self.allDevices = finalData2.owndevices + finalData2.deldevices
    self.allDevices = self.allDevices.sorted(by: {$0.givenName.lowercased() < $1.givenName.lowercased()})
    self.delegate?.getDeviceData(self, deviceData: self.allDevices)
    self.shortcutTable.reloadData()
    self.sendTopicListSocket(topics: topicList)
}

// HomeVC中UITableView的cellForRowAt实现
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = shortcutTable.dequeueReusableCell(withIdentifier: "shortcutCell", for: indexPath) as! shortcutCell
    cell.delegate = self
    cell.deviceArray = self.allDevices
    return cell
}

UITableViewCell代码

class shortcutCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    var deviceArray : Array<device>?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        let homeVC = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController
        homeVC!.delegate = self
    }
    
    func getDeviceData(_ controller: HomeViewController, deviceData: [device]) {
        self.deviceArray = deviceData
        self.deviceArray?.forEach({ device in
            self.deviceNames?.append(device.name)
            self.deviceIDs?.append(device._id)
        })
    }
    
    // CollectionView相关方法
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        print("DEVICE ARRAY COUNT", self.deviceArray?.count as Any)
        return self.deviceArray?.count ?? 1
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print(self.deviceArray)
        print(indexPath.row)
        print(self.deviceArray?[indexPath.row].givenName)
    }
}

解决方案

问题1:代理方法getDeviceData未被调用

原因:在shortcutCell的awakeFromNib中,你新实例化了一个HomeViewController对象并设置代理,但这个新实例和当前正在运行的HomeVC不是同一个对象。API请求是在原HomeVC中执行的,所以代理方法永远不会触发。此外,你已经在cellForRowAt中直接给cell赋值deviceArray,完全不需要代理传递数据。

修复:删除shortcutCell中awakeFromNib内的HomeVC实例化和代理代码,同时可以移除整个homeVCdelegate协议(因为没用了):

// 移除shortcutCell中的这段代码
override func awakeFromNib() {
    super.awakeFromNib()
    // 删掉以下两行
    // let homeVC = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as? HomeViewController
    // homeVC!.delegate = self
}

// 同时可以删除ViewController中的homeVCdelegate协议声明和delegate变量

问题2:CollectionView数据源方法中deviceArray为nil

原因:UITableViewCell复用机制下,CollectionView的数据源方法可能在deviceArray赋值前就被调用;另外,赋值deviceArray后没有主动刷新CollectionView,导致数据不同步。

修复:

  1. 给shortcutCell的deviceArray添加属性观察者,值变化时自动刷新CollectionView:
class shortcutCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    var deviceArray : Array<device>? {
        didSet {
            // 替换成你的CollectionView变量名,比如collectionView
            self.collectionView.reloadData()
            // 如果需要同步deviceNames和deviceIDs,也放在这里
            self.deviceNames?.removeAll()
            self.deviceIDs?.removeAll()
            self.deviceArray?.forEach({ device in
                self.deviceNames?.append(device.name)
                self.deviceIDs?.append(device._id)
            })
        }
    }
    
    // ... 其他代码
}
  1. 修改numberOfItemsInSection的默认返回值为0,避免显示空单元格:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    print("DEVICE ARRAY COUNT", self.deviceArray?.count as Any)
    return self.deviceArray?.count ?? 0
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:20:27