【发布时间】:2018-05-07 05:56:16
【问题描述】:
从 RxSwift4 开始,Variable 移至 Deprecated.swift,这标志着将来可能会弃用 Variable。向Variable 提议的替代方案是BehaviorRelay。在发布这个问题时,由于我使用BehaviorRelay 在网络上找不到太多教程,所以我在 SO 中发布了这样一个基本问题。
假设我有一个 webService 调用正在进行,并且我收到一大块 JSONArray 数据,在逐个解析 JSON 对象时,我会更新变量的 value 属性
这是我的变量声明
var myFilter = Variable<[MyFilterModel]>([MyFilterModel(data: "{:}")])
每次我将变量更新为获取新元素时
myFilter.value.append(newModel)
由于 Variable 绑定到 CollectionView,collectionVie 会立即使用新添加的对象更新其 UI。
行为中继问题
现在我的声明看起来像
var myFilter = BehaviorRelay<[MyFilterModel]>(value: [MyFilterModel(data: "{:}")])
但最大的问题是myFilter.value 是只读。很明显
myFilter.value.append(newModel)
不是解决方案。我发现我可以改用accept。
但是现在当我尝试解析每个元素作为响应并更新 myFilter 的值时
self?.expertsFilter.accept(newModel)
上面的语句给出了错误引用
无法将 NewModel 的值转换为预期的争论类型 [新模型]
显然,它需要一个数组而不是单个元素。
解决方法:
解决方案 1:
所以一种解决方案是将所有响应累积在一个临时数组中,一旦完成就触发self?.expertsFilter.accept(temporary_array)
解决方案 2:
如果我必须在解析每个元素时向订阅者发送onNext 事件,我需要将 self?.expertsFilter 的值复制到新数组中,将新解析的元素添加到其中并返回新数组。
解决方案 3:
摆脱BehaviorRelay并使用BehaviorSubject/PublishSubject
前两个听起来令人沮丧,因为在解析每个元素时可能需要触发 UI,我不能等到整个响应被解析。所以很明显solution1用处不大。
第二种解决方案更可怕,因为它每次发送 onNext 事件时都会创建一个新数组(我知道它是临时的,将被释放)。
问题:
因为BehaviorRelay 被提议作为Variable 的替代品,我处于两难境地,我是否正确使用accept?有没有更好的方法来解决它?
请帮忙
【问题讨论】:
-
@maxim-volgin : 请看一下
-
你有什么新的数组解决方案吗?
-
我无法访问 BehaviorRelay。任何想法为什么?我的 pod 文件只指向 pod 'RxSwift', '~> 4.0'
-
@shabarinath-pabba:确保你在使用
BehaviorRelay的文件中使用import RxSwift import RxCocoa导入RxSwift和RxCocoa。BehaviorRelay在 RxSwift 中声明,所以逻辑上导入import RxSwift就足够了,但如果你将它与 Cocoa 一起使用,import RxCocoa将是必要的 -
@ShabarinathPabba 导入 RxCocoa。 BehaviorRelay 在 RxCocoa 中声明。
标签: rx-swift