RxSwift DisposeBag 和 UITableViewCell

RxSwift DisposeBag and UITableViewCell

我有一个 UITableViewCell,它包含一个 UICollectionView。 我将集合视图的数据放在数据源的表视图中。

class HomeTableViewCell: UITableViewCell {
    var disposeBag = DisposeBag()
    @IBOutlet weak var collectionItems: UICollectionView!
    var listItem: PublishSubject<HomeResultModel> = PublishSubject<HomeResultModel>()
    let dataSource = RxCollectionViewSectionedReloadDataSource<SectionOfMenuData>(configureCell: {(_, _, _, _) in
        fatalError()
    })

override func awakeFromNib() {
    super.awakeFromNib()
    setup()
    setupBinding()
}

override func prepareForReuse() {
    disposeBag = DisposeBag()
}

func setup() {
    collectionItems.register(UINib(nibName: MenuCollectionViewCell.identifier, bundle: nil), forCellWithReuseIdentifier: MenuCollectionViewCell.identifier)
    collectionItems.register(UINib(nibName: RecipeCollectionViewCell.identifier, bundle: nil), forCellWithReuseIdentifier: RecipeCollectionViewCell.identifier)
    collectionItems.rx.setDelegate(self).disposed(by: disposeBag)
    
    collectionItems.rx.modelAndIndexSelected(HomeListModel.self).subscribe { (model, index) in
        if let recipesID = model.recipesID {
            tlog(tag: self.TAG, sLog: "recipesID : \(recipesID)")
            self.recipeIdSelected.onNext("\(recipesID)")
        }
    }.disposed(by: disposeBag)
    
    dataSource.configureCell = { (dataSource, collectionView, indexPath, item) -> UICollectionViewCell in
        let cellType = dataSource.sectionModels.first?.type ?? .recipeCell
        if cellType == .menuCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuCollectionViewCell.identifier, for: indexPath) as! MenuCollectionViewCell
            cell.showInfo(item)
            return cell
        } else {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RecipeCollectionViewCell.identifier, for: indexPath) as! RecipeCollectionViewCell
            cell.showInfo(item.recipesName ?? "", imageLink: item.imageThumb ?? "")
            return cell
        }
    }
}

func setupBinding() {        
    listItem.map { model -> [SectionOfMenuData] in
        let modelID = try JSONEncoder().encode(model.id)
        let modelResultID = String.init(data: modelID, encoding: .utf8)!
        return [SectionOfMenuData(type: modelResultID == "0" ? .menuCell : .recipeCell, id: modelResultID, items: model.list)]
    }.bind(to: collectionItems.rx.items(dataSource: dataSource))
    .disposed(by: disposeBag)
}
}

我使用代码为 tableviewcell 传递数据:

let dataSource = RxTableViewSectionedReloadDataSource<SectionOfHome> { dataSource, tableView, indexPath, item in
            let cell = tableView.dequeueReusableCell(withIdentifier: HomeTableViewCell.identifier, for: indexPath) as! HomeTableViewCell
            cell.listItem.onNext(item)
            return cell
        }

首先显示ok,但是当滚动tableview时,我重置了DisposeBag in:

func prepareForReuse{ 
    disposeBag = DisposeBag()
}

等表格视图显示空白。 我在这方面错到什么程度了?

当单元格被重复使用并且永远不会重新创建时,您对 listItems 的订阅将被处理掉。您应该 运行 awakeFromNib 中的一次性任务,并将单个单元格特定绑定移动到一个函数,您可以在 prepareForReuse.

中重置 disposeBag 后调用该函数