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

TableView嵌套CollectionView向新ViewController传参异常问题

问题根源与解决方案

嘿,我一眼就揪出问题所在了——你误用了类变量(class var),这才导致数据不断累积,传参时带出一堆多余内容!

核心问题分析

  1. HeadlineCell中的transferData是类变量:类变量属于整个类,所有HeadlineCell实例共享同一个数组。每次调用updateUI时你都执行self.transferData.append(latest),这就会把所有加载过的LatestNews对象都塞进同一个全局数组里,点击时自然传的是一堆数据,而非当前选中的单个Item。
  2. HeadlineRow中的latest也是类变量:同样的道理,所有TableViewCell会共享同一组数据源,这在TableView复用的时候也会引发各种奇怪问题。

分步修复代码

1. 修复HeadlineCell:用实例变量存单个对象

把类变量改成实例变量,而且每个cell只需要存单个LatestNews对象,不需要数组:

class HeadlineCell: UICollectionViewCell {
    // 把class var改成实例变量,存储单个对象而非数组
    var transferData: LatestNews?

    func updateUI(latest: LatestNews) {
        storyTextView.text = latest.headline
        self.thumbnail.sd_setImage(with: URL(string: "\(latest.app_img)"))
        // 直接赋值单个对象,不要append!
        self.transferData = latest
    }
}

2. 修复HeadlineRow:改用实例变量数据源,优化选中逻辑

把类变量latest改成实例变量,同时选中时直接从数据源取对应项,比从cell拿更可靠:

class HeadlineRow: UITableViewCell {
    // 把class var改成实例变量,每个cell持有自己的数据源
    var latest = [LatestNews]()
    weak var delegate: YourDelegateProtocol? // 记得替换成你的代理协议

    // ...其他代码...

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        // 直接从当前cell的数据源中取选中的单个对象
        let selectedNews = latest[indexPath.row]
        // 包装成数组传给代理(如果代理方法要求数组的话,或者直接改代理方法传单个对象)
        delegate?.pushToNewsVC(latestNews: [selectedNews])
    }
}

3. 简化主VC的传参逻辑(可选但更清晰)

可以去掉中间变量transferToNewsVC,直接把选中的对象作为sender传递:

// 先确保你的代理协议定义合理,比如改成传单个对象更直观:
protocol HeadlineRowDelegate: AnyObject {
    func pushToNewsVC(latestNews: LatestNews)
}

// 主VC实现代理方法:
func pushToNewsVC(latestNews: LatestNews) {
    // 直接把选中的对象作为sender传给segue
    performSegue(withIdentifier: "NewsVC", sender: latestNews)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "NewsVC", 
       let destination = segue.destination as? NewsVC,
       let selectedNews = sender as? LatestNews {
        // 直接给目标VC的数组赋值单个对象(如果目标VC只需要展示选中项的话)
        destination.latestNews = [selectedNews]
        destination.SuggestedLatestNews = self.latest
    }
}

额外提醒

以后要区分类变量(class var/static var)和实例变量:类变量是全局共享的,适合存整个类的通用配置;实例变量是每个对象独有的,用来存单个实例的状态数据,像cell的数据源、单个Item的数据这类,一定要用实例变量!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:54:16