rxswift 绑定(onNext:VS 订阅(onNext:
Posted
技术标签:
【中文标题】rxswift 绑定(onNext:VS 订阅(onNext:【英文标题】:rxswift bind(onNext: VS subscribe(onNext: 【发布时间】:2019-03-22 06:50:34 【问题描述】:我有两个问题:
-
'bind(onNext:' 和 'subscribe(onNext:' 有什么区别?
struct Info
var index: Int?
var data: String?
let infoData: BehaviorRelay<Info> = BehaviorRelay<Info>(value: Info())
var osInfo: Observable<String> return self.infoData.map( return $0.data ).distinctUntilChanged()
osInfo.bind (target) in
print("bind!")
.disposed(by: self.disposeBag)
osInfo.subscribe (target) in
print("subscribe!")
.disposed(by: self.disposeBag)
-
a 没有 asObservable(),但可执行性很好。 a和b有什么区别?
a. var osInfo: Observable<String> return self.infoData.map( return $0.data ).distinctUntilChanged()
b. var osInfo: Observable<String> return self.infoData.asObservable().map( return $0.data ).distinctUntilChanged()
【问题讨论】:
【参考方案1】:'bind(onNext:' 和 'subscribe(onNext:' 有什么区别?
如果我们检查 bind(...)
的实现,我们会发现它什么也不做,只是在底层使用 subscribe(...)
并在 Debug 中崩溃并出现错误:
/**
Subscribes an element handler to an observable sequence.
In case error occurs in debug mode, `fatalError` will be raised.
In case error occurs in release mode, `error` will be logged.
- parameter onNext: Action to invoke for each element in the observable sequence.
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
public func bind(onNext: @escaping (E) -> Void) -> Disposable
return subscribe(onNext: onNext, onError: error in
rxFatalErrorInDebug("Binding error: \(error)")
)
通过使用bind(onNext)
,您可以表示该流不应该发出错误并且您只对项目事件感兴趣。
因此,当您对错误/完成/处置事件感兴趣时应使用subscribe(onNext:...)
,否则应使用bind(onNext...)
。但由于它是RxCocoa
的一部分而不是RxSwift
,所以我通常在任何地方都使用subscribe
。
a 没有 asObservable(),但可执行性很好。 a和b有什么区别?
map(...)
是在ObservableType
上声明的函数并返回新的Observable
让我们从ObservableType
开始。ObservableType
是只需要一种方法的协议:subscribe(...)
,这允许他创建func asObservable()
的默认实现。
对您而言,这意味着您可以从任何符合ObservableType
的类型创建Observable
。
/// Represents a push style sequence.
public protocol ObservableType : ObservableConvertibleType
func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E
extension ObservableType
/// Default implementation of converting `ObservableType` to `Observable`.
public func asObservable() -> Observable<E>
// temporary workaround
//return Observable.create(subscribe: self.subscribe)
return Observable.create o in
return self.subscribe(o)
因此,每次您调用 asObservable()
underhood RxSwift 时,都会在您的流周围创建新的 Observable
包装器。
如果您检查BehaviourRelay
的来源,您会发现它也符合ObservableType
。所以你可以随时从中创建Observable
:
public final class BehaviorRelay<Element>: ObservableType ...
现在让我们检查map
函数:
extension ObservableType
/**
Projects each element of an observable sequence into a new form.
- seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html)
- parameter transform: A transform function to apply to each source element.
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
public func map<R>(_ transform: @escaping (E) throws -> R)
-> Observable<R>
return self.asObservable().composeMap(transform)
正如预期的那样,map
只需在内部调用asObservable()
并在新的Observable
上进行操作。
如果我们“解包”map
调用,我们将得到:
var osInfoA: Observable<String>
return infoData
.asObservable()
.composeMap $0.data
.distinctUntilChanged()
var osInfoB: Observable<String>
return infoData
.asObservable()
.asObservable()
.composeMap $0.data
.distinctUntilChanged()
当然它不会编译,因为composeMap
是内部函数,但你明白了主要思想。
在其他运算符之前调用 asObservable
是多余的(大多数运算符在 ObservableType
上定义)并且只会增加少量开销。
【讨论】:
以上是关于rxswift 绑定(onNext:VS 订阅(onNext:的主要内容,如果未能解决你的问题,请参考以下文章