gpt4 book ai didi

ios - ReactiveSwift 一对多信号订阅和相关的内存开销

转载 作者:行者123 更新时间:2023-12-04 08:17:05 27 4
gpt4 key购买 nike

我有一个简单的信号,在其中一个应用程序组件中,它返回一组项目:

var itemsSignal: Signal<[Item], Never>
那些项目 可能包含以表格 View 形式呈现在屏幕上的数据的更新。任务是将更新应用于屏幕上存在的单元格。
关于如何做到这一点,我能想到有两种可能的方法。该应用程序是用 MVVM 风格编写的,但我只是为了举例。
第一种方式是订阅这个信号 一次 在 View Controller 代码级别,然后在 observeValues在我们收到屏幕上项目更新的任何地方进行块检查,并使用一些 for 循环更新相应单元格的状态。这样我们将只有一个订阅,但这会引入不必要的,在我看来,代码耦合,当我们基本上使用 View Controller 级别的代码将更新从源传递到屏幕上的单个单元格时。
第二种方法是从每个单独的单元格(实际上是单元格的 View 模型)订阅这个信号并应用一些像这样的过滤:
disposables += COMPONENT.itemsSignal
.flatten()
.filter({ $0.itemId == itemId })
.observeValues({
...
})
但这会产生 多个 订阅 - 每个单元格一个。
我实际上更喜欢第二种方法,因为从设计的角度来看它更清晰,在我看来,因为它不会泄漏任何不必要的知识来查看 Controller 级代码。并且在不同屏幕上重复使用相同的单元格时,这种自我更新行为将被继承,并且可以立即使用。
问题是,由于多次订阅,第二种方法的内存/cpu 贵多少?在这个项目中,我们使用 ReactiveSwift ,但我认为这与其他相关 Rx图书馆也是如此。

最佳答案

在 RxSwift 中,我们的 RxCocoa 库已经实现了你的第一个想法,并在 tableView 上做了一个简单的 reloadData。

items
.bind(to: tableView.rx.items) { (tableView, row, element) in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(element) @ row \(row)"
return cell
}
或者您可以告诉库单元格的类型,它会为您创建单元格:
items
.bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, element, cell) in
cell.textLabel?.text = "\(element) @ row \(row)"
}
我们还有一个您没有提到的选项。单个订阅但更智能的数据源,能够根据传入的序列元素的相等性添加和删除单个单元格。这是在一个名为 RxDataSources 的单独库中。 .
作为对有关资源的基本问题的回答......我经常使用混合解决方案,其中有一个仅包含对象 ID 序列的 Observable;这是您的第一个想法,但它只负责项目的插入和删除。我将制作 [ID: Info] 的第二个 Observable每个当前存在的单元订阅。在单元创建/重用时,它被赋予一个 ID 并订阅第二个 observable 并过滤掉它感兴趣的信息。在单元的 prepareForReuse 中。它取消订阅。
由于每个现有单元格只有一个订阅,因此新订阅实际上并没有那么多(取决于单元格的高度和表格 View 的高度。)我的应用程序通常在任何时间运行数千个订阅,因此从这种“每个单元”方法添加的额外订阅数量甚至不明显。

关于ios - ReactiveSwift 一对多信号订阅和相关的内存开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65659620/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com