在RxSwift中直接为UITableView访问BehaviorRelay值有效吗?

问题描述 投票:0回答:1

我正在使用 RxSwift,并且有一个场景,我在 ViewModel 中使用BehaviorRelay 来保存 UITableView 的数据数组。我已经设置了对此BehaviorRelay 的订阅,专门用于在我的UITableView 上触发reloadData。但是,我想知道在 UITableViewDataSource 方法中访问数组数据的最佳实践。

这是我正在做的事情的简化版本:

class ViewModel {
    let dataRelay = BehaviorRelay<[Section]>(value: [])
}

class ViewController: UIViewController {
    let viewModel = ViewModel()
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        //trigger reloadData
        viewModel.dataRelay
            .subscribe(onNext: { [weak self] _ in
                self?.tableView.reloadData()
            })
            .disposed(by: disposeBag)

        // Trigger data fetching
        viewModel.fetchData()
    }

    
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.dataRelay.value.count //here's the value
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: HomeTableViewCell.identifier, for: indexPath) as! HomeTableViewCell
        let data = viewModel.dataRelay.value //here's the value
        
        switch data[indexPath.row] {
        case .carousel(let title, _):
            cell.title.text = title
        case .standard(let title, _):
            cell.title.text = title
        }
        return cell
    }
    
    
}

这是一种有效且推荐的方法,还是我应该创建另一个变量来保存数据并在订阅中更新它?

在这种情况下直接访问值有哪些潜在的优点和缺点?在使用 RxSwift 和 UITableViews 时我应该注意哪些注意事项?

我不使用bind(to:),因为我不想使用RxDataSource来处理复杂数据

感谢您的指导或见解!

swift uikit tableview rx-swift reactive
1个回答
0
投票

这里似乎有些混乱...最佳实践是使用

bind(to:)
并且您不需要导入 RxDataSources 即可使用它...

viewModel.dataRelay
    .bind(
        to: tableView.rx.items(cellIdentifier: HomeTableViewCell.identifier, cellType: HomeTableViewCell.self)
    ) { _, item, cell in
        switch item {
        case .carousel(let title, _):
            cell.title.text = title
        case .standard(let title, _):
            cell.title.text = title
        }
    }
    .disposed(by: disposeBag)

上述行为与您正在尝试的行为相同,并且是标准做法。

© www.soinside.com 2019 - 2024. All rights reserved.