我有两个问题:
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)
Run Code Online (Sandbox Code Playgroud)
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() }
Run Code Online (Sandbox Code Playgroud)
如果我们检查实现,bind(...)我们发现它什么也没做,只是subscribe(...)在调试错误时使用了底层功能并崩溃:
/**
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)")
})
}
Run Code Online (Sandbox Code Playgroud)
通过使用bind(onNext)您可以表示该流永远不会发出错误,并且您仅对项目事件感兴趣。
因此,subscribe(onNext:...)当您对错误/完成/已处置事件以及bind(onNext...)其他事件感兴趣时,应该使用。但是由于它是其中的一部分,RxCocoa所以RxSwift我通常不在subscribe各处使用。
map(...)是在函数上声明ObservableType并返回newObservable
让我们从开始ObservableType。
ObservableType是只需要一种方法的协议:subscribe(...),这使他可以创建的默认实现func asObservable()。
对您来说,这意味着您可以Observable从符合的任何类型创建ObservableType。
/// 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,每次调用asObservable()底层RxSwift都会Observable在流周围创建新的包装器。
而且,如果您检查来源,BehaviourRelay您也会发现它也符合ObservableType。因此您可以Observable随时从中创建:
public final class BehaviorRelay<Element>: ObservableType { ... }
Run Code Online (Sandbox Code Playgroud)
现在让我们检查一下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)
}
}
Run Code Online (Sandbox Code Playgroud)
如预期的那样,map只需打入电话asObservable()并在new上进行操作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()
}
Run Code Online (Sandbox Code Playgroud)
确保它不会编译,因为它composeMap是内部函数,但是您有了主要想法。在其他运算符之前进行
调用asObservable是多余的(大多数运算符在上定义ObservableType),只会增加少量开销。