rxswift 绑定(onNext:VS 订阅(onNext:

rxswift bind(onNext: VS subscribe(onNext:

我有两个问题:

  1. '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 [=10=].data }).distinctUntilChanged() }

osInfo.bind { (target) in
    print("bind!")
    }.disposed(by: self.disposeBag)

osInfo.subscribe { (target) in
    print("subscribe!")
    }
    .disposed(by: self.disposeBag)
  1. a 没有 asObservable(),但可执行性很好。 a 和 b 有什么区别?
a. var osInfo: Observable<String> { return self.infoData.map({ return [=11=].data }).distinctUntilChanged() }
b. var osInfo: Observable<String> { return self.infoData.asObservable().map({ return [=11=].data }).distinctUntilChanged() }

'bind(onNext:'和'subscribe(onNext:'有什么区别?

如果我们检查 bind(...) 的实现,我们发现它除了使用 subscribe(...) underhood 之外什么也没做,并在 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 { [=14=].data }
        .distinctUntilChanged()
}
var osInfoB: Observable<String> {
    return infoData
        .asObservable()
        .asObservable()
        .composeMap { [=14=].data }
        .distinctUntilChanged()
}

肯定不会编译,因为 composeMap 是内部函数,但您已经掌握了主要思想。
在其他运算符之前调用 asObservable 是多余的(大多数运算符在 ObservableType 上定义)并且只会增加少量开销。