RxSwift概览&&核心Observable

1,483 阅读5分钟

Observable

简介

Observable也是一个序列,其核心就是异步操作

Observable的生命周期:

  1. Observable发射包含元素的事件
  2. 它可以一直发射事件直到终止事件发生,比如发射完成信号或者错误信号
  3. 一旦序列被终止了,它就不能再发射任何事件了

其中事件Event在源码中是被包装成枚举

/// Represents a sequence event.
///
/// Sequence grammar: 
/// **next\* (error | completed)**
public enum Event<Element> {
    /// Next element is produced.
    case next(Element)

    /// Sequence terminated with an error.
    case error(Swift.Error)

    /// Sequence completed successfully.
    case completed
}”

Observable的快速创建方法

just

image.png

just将传入的item转化为发射itemObservable

just有些类似于from,但是from会深入数组、迭代器或者类似的对象中将其中的内容作为要发射的item提取出来,而just只是简单的发射你传入的item

注意,如果你将null传递给just,它将返回一个发出null作为itemObservable。不要错误地认为这将返回一个空的可观察对象(一个根本不发出任何item的对象)

let one = 1
let two = 2
let three = 3

let observable = Observable<Int>.just(one)

observable.subscribe { event in

        print(event)

 }.disposed(by: disposeBag)
 

----打印结果-----
 
next(1)

completed

of

of可以传多个同类型参数

let observable2 = Observable.of(one, two, three)
observable2.subscribe { event in

    print(event)

}.disposed(by: disposeBag)

----打印结果-----

next(1)
next(2)
next(3)
completed
let observable3 = Observable.of([one, two, three], ["12333"])
observable3.subscribe { element in

    print(element)

}

onCompleted: {

    print("完成")

}

onDisposed: {

    print("observable3 disposed")

}.disposed(by: disposeBag)

----打印结果-----
[1, 2, 3]
["12333"]
完成
observable3 disposed

from

from将各种其他对象和数据类型转换为 Observable image.png

当你使用可观察对象时,如果你想要使用的所有数据都可以表示为可观察对象,而不是可观察对象和其他类型的混合,这样会更方便。这允许你使用一组操作符来管理数据流的整个生命周期。通过明确的转换一些对象将它们变为可观察的,你将允许它们与其它可观察对象进行平等的交互。

出于这个原因,大多数ReactiveX实现都有允许你将某些特定于语言的对象和数据结构转换为Observables的方法

例如,可迭代对象可以被认为是一种同步的可观察对象;未来作为一种总是发射单个item的可观察对象

let observable4 = Observable.from([one, two, three])

observable4.subscribe { event in

    print(event)

}.disposed(by: disposeBag)

----打印结果-----

next(1)
next(2)
next(3)
completed

总结:

  • just仅支持单个参数传递,而且传递什么订阅后便得到什么
  • of可以传递多个同类型的参数,同样也是传递什么订阅后便得到什么
  • from传递数组,但是它会将数组中的元素拿出来

empty

//empty没有类型能推断,所以必须显示的写明void

let observable = Observable<Void>.empty()

observable.subscribe { _ in

    print("next")

} onError: { error in

    print(error)

} onCompleted: {

    print("完成")

} onDisposed: {

    print("disposed")

}.disposed(by: disposeBag)

----打印结果-----
完成
disposed

如果你想得到一个立即终止或者你有意想要0个值的可观察队列,你就可以使用empty

never

empty不同,never创建的可观察序列不会发出任何信号,也不会终止。它可以用来表示无限的持续时间


let observable = Observable<Void>.never()
observable.subscribe { e in

    print(e)

} onError: { error in

    print(error)

} onCompleted: {

    print("完成")

} onDisposed: {

    print("disposed")

}.disposed(by: disposeBag)

----打印结果-----


结果是没有任何打印,甚至连完成销毁也没有打印,所以如何知道这个队列还在运行??

Observable的源码分析

序列的三步:

  • 创建
  • 订阅
  • 销毁

let ob = Observable<Any>.create { observer in

    observer.onNext("12345")

    observer.onCompleted()

    return Disposables.create()

}



ob.subscribe { text in

    print("订阅到了\(text)")

} onError: { error **in**

    print(error)

} onCompleted: {

    print("完成")

} onDisposed: {

    print("销毁")

}.disposed(by: disposedBag)

---打印结果---

订阅到了12345
完成
销毁

从上面代码结果来分析很明显应当是在订阅后即subscribe的回调中先执行了上面create方法的回调,因为create方法的回调中是发送信号,只有先发送了信号在订阅中才能收到信号,但是来看到源码里

create中仅仅创建了一个AnonymousObservable对象并且将回调当做参数发给了它 image.png

AnonymousObservable继承于Producer

在初始化方法中也仅仅是将收到的参数也就是上一步的闭包保存了而已 image.png

create中没找到相关线索,接下来先看看subscribe方法

可以看到这里内部主要生成一个AnonymousObserver类型的observer对象,这里同样是将尾随闭包存放于内部

image.png

最主要的是底下self.asObservable().subscribe(observer)这里selfAnonymousObservable,刚说过它继承于Producer,在调用subscribe方法的时候,其实是调用其父类也就是Producersubscribe方法

image.png

这里会执行else的分支代码,重点在self.run这里,selfAnonymousObservable,所以会调用自己的run方法

image.png

会调用sink.run也就是AnonymousObservableSinkrun方法

image.png

这里run方法内的调用parent就是AnonymousObservable对象,这里就是直接调用了之前保存的回调,也就是最开始创建信号create方法后面的尾随闭包,直接调用了这个闭包

Observable核心图解如下:

image.png

Observable类分析

刚才分析了AnonymousObservable发现它的父类是Producer,而Producer的父类是ObservableObservable是整个链条的基类,它只是要遵循ObservableType协议

image.png

ObservableType协议中有方法subscribe,也就是说只要遵从这个协议的对象都可以进行订阅,但是如果不是属于这个继承链的对象虽然也可以调用订阅方法,但是最好还是使用asObservable先转换为Observable为好

例如下面代码这样写也不会报错,但是最好不要这么写

UISwitch().rx.value.subscribe { event in

    print(event)

}.disposed(by: disposedBag)

先使用asObservable转化后再订阅

UISwitch().rx.value.asObservable().subscribe { event in

    print(event)

}.disposed(by: disposedBag)

这里的asObservable()是原先的ControlProperty类型的value转变为Observable的类型

image.png