如何在 RxSwift 中使用 BehaviorRelay 作为变量的替代? [英] How to use BehaviorRelay as an alternate to Variable in RxSwift?

查看:216
本文介绍了如何在 RxSwift 中使用 BehaviorRelay 作为变量的替代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 RxSwift4 开始,Variable 被移到 Deprecated.swift 中,这标志着 Variable 未来可能被弃用.Variable 的替代方案是 BehaviorRelay.在发布这个问题时,因为我在使用 BehaviorRelay 的网络上找不到很多教程,所以我在 SO 中发布了这样一个基本问题.

As of RxSwift4, Variable is moved to Deprecated.swift marking the possible deprecation of Variable in future. An alternate proposed to Variable is BehaviorRelay. While posting this question, as I could not find much of the tutorial on web using BehaviorRelay am posting such a fundamental question here in SO.

假设我有一个 webService 调用,我收到了一块 JSONArray 的数据,在一个一个解析 JSON 对象时我更新了我的变量的 value 属性

Assume I have a webService call going on and I receive a chunk of data which is JSONArray, on parsing JSON object one by one I update my Variable's value property

这是我的变量声明

var myFilter = Variable<[MyFilterModel]>([MyFilterModel(data: "{:}")])

每次我将变量更新为一个新元素

on getting a new element each time I would update my Variable as

myFilter.value.append(newModel)

由于 Variable 绑定到 CollectionView,collectionVie 会立即使用新添加的对象更新其 UI.

As Variable was bind to CollectionView, collectionVie would update its UI immediately with the newly added object.

BehaviorRelay 的问题

现在我的声明看起来像

var myFilter = BehaviorRelay<[MyFilterModel]>(value: [MyFilterModel(data: "{:}")])

但最大的问题是 myFilter.valuereadOnly.很明显

But biggest issue is myFilter.value is readOnly. So obviously

myFilter.value.append(newModel) 

不是解决方案.我发现我可以使用 accept 而不是.

is not a solution. I figured out that I can use accept rather.

但是现在当我尝试解析每个元素作为响应并更新 myFilter 的值时

But now when I try to parse each element in response and update the value of myFilter

self?.expertsFilter.accept(newModel)

上面的语句给出错误引用

The above statement gives error quoting

无法将 NewModel 的值转换为预期的争论类型[新模型]

Can not convert the value of NewModel to expected arguement type [NewModel]

显然,它需要一个数组而不是单个元素.

Obviously, its expecting a array and not a individual element.

解决方法:

解决方案 1:

所以一种解决方案是将所有响应累积在一个临时数组中,一旦完成触发 self?.expertsFilter.accept(temporary_array)

So one solution is accumulate all the response in a temporary array and once done trigger self?.expertsFilter.accept(temporary_array)

解决方案 2:

如果我必须在解析每个元素时向订阅者发送 onNext 事件,我需要将 self?.expertsFilter 的值复制到新数组,将新解析的元素添加到其中并返回新的数组.

If I have to send onNext event to subscriber on parsing each element, I need to copy the value of self?.expertsFilter to new Array, add the newly parsed element to it and return the new array.

解决方案 3:

去掉BehaviorRelay,改用BehaviorSubject/PublishSubject

前两个听起来令人沮丧,因为可能需要在解析每个元素时触发 UI,我等不及要解析整个响应.所以很明显,解决方案 1 没有多大用处.

First two sounds depressing, because there may be a need to trigger UI on parsing each element I cant wait till entire response is parsed. So obviously solution1 is not much of use.

第二种解决方案更可怕,因为它每次发送 onNext 事件时都会创建一个新数组(我知道它是临时的,将被释放).

Second solution is much more horrible because it creates a new array (I know its temporary and will be released) every time to send onNext event.

问题:

因为 BehaviorRelay 被提议作为 Variable 的替代品,所以我陷入了两难,是否正确使用了 accept??有没有更好的方法来解决它?

Because BehaviorRelay is proposed as a alternate to Variable am in dilemma, am using accept correctly?? Is there a better way to solve it?

请帮忙

推荐答案

您是否考虑过简单地从中继上的现有值创建一个新数组,附加,然后调用 accept?

Have you considered simply creating a new array from the existing value on the relay, appending, then calling accept?

myFilter.accept(myFilter.value + [newModel])

这篇关于如何在 RxSwift 中使用 BehaviorRelay 作为变量的替代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆