example(of: "PublicSubject") { let disposeBag = DisposeBag() //1 let subject = PublishSubject<String>() //2 subject.onNext("Is anyone listening?") //3 subject.subscribe { print("第1个订阅者",$0.element ?? $0) }.addDisposableTo(disposeBag) //4 subject.on(.next("1")) subject.onNext("2") //5 subject.subscribe { event in print("第2个订阅者", event.element ?? event) }.addDisposableTo(disposeBag) //6 subject.onNext("3") //7 subject.onCompleted() //8 subject.onNext("5") //9 subject.subscribe{ print("第3个订阅者", $0.element ?? $0) }.addDisposableTo(disposeBag) //10 subject.onNext("?") // 无效 } 执行结果和分析: --- Example of: PublicSubject — 第1个订阅者 1 第1个订阅者 2 第1个订阅者 3 第2个订阅者 3 第1个订阅者 completed 第2个订阅者 completed 第3个订阅者 completed 1: 创建一个公开对象,该对象可以接收信息并发布给订阅者(publisher),类型为string,所以仅仅只接受string类型,一旦被初始化,就准备接收消息 2 :输入一个新的字符串到subject。但是现在并不会有什么内容被打印,因为还没有订阅者(也叫观察者) 3: 创建观察者,但是还是没有任何内容输出?why? why? why? 是因为,我们必须先为subject添加订阅,然后再添加内容,才能得到相应的内容 4: 再此发送消息即添加内容,那么这次可以看到内容了。因为subject已经有订阅者了,所以它将发送text,注意:on(.next(_:) 跟onNext方法是一样的功能,只不过onNext更容易理解,内部包装了一下 5: 添加第二个订阅者 6: 该消息会发送给所有订阅者,这里有两个订阅者,所以都将收到事件 7: 当publishSubject接受.completed或者.error事件,会发送停止事件给所有订阅者,并且不再发送消息即.next事件。但是它将重新发送它的停止事件给将来的订阅者。 8: 为subject发送消息,但是并没有效果,会被忽略掉,因为subject已经终止,即观察者序列已经结束,被终止 9: 再一次为subject进行订阅,并添加到处理包中,仅仅打印完成事件,即终止事件 10: 观察者序列终止,消息发送无效
//建立一个工具打印相应的信息 func print<T: CustomStringConvertible>(label: String, event: Event<T>) { print(label, event.element ?? event.error ?? event) }
简单使用
//定义一个错误枚举 enum MyError: Error { case anError } example(of: "BehaviorSubject") { let disposeBag = DisposeBag() //1 let subject = BehaviorSubject(value: "Initial value") //2 subject.onNext("x") //3 subject.subscribe { print(label: "1)", event: $0) }.addDisposableTo(disposeBag) //4 subject.onNext("y") //5 subject.onError(MyError.anError) //6 subject.subscribe { print(label: "2)", event: $0) }.addDisposableTo(disposeBag) //7 subject.onNext("z") } 执行结果和分析: --- Example of: BehaviorSubject --- 1) x 1) y 1) anError 2) anError 1:创建一个BehaviorSubject,并拥有一个初始值。注意:因为BehaviorSubject经常发送最新最近的元素,所以你不能创建一个BehaviorSubject实例而不提供默认的初始值。如果你不能提供初始值,那么获取就应该使用 PublishSubject 2:发送一个消息x 3:为subject创建一个订阅者,因为之前发送了消息x,所以打印消息x。如果之前不发送消息x,那么没有为subject添加其它的元素,只有初始值,所以会发送初始值给订阅者 4:发送消息y,订阅者将接收消息y 5:为subject添加error,发送错误信息,观察者序列终止 6:为subject创建一个新的订阅者,只为新的订阅者发送上一次的错误信息 7:无效,因为subject已经终止 注意:BehaviorSubject对于一个视图想显示最近的数据是非常有用的。对于个人中心页面的控件,在app获取新数据之前,先显示最近的数据,在获取新数据之后显示新数据。
example(of: "replay") { let disposeBag = DisposeBag() //1 let subject = ReplaySubject<String>.create(bufferSize: 2) //2 subject.onNext("1") subject.onNext("2") subject.onNext("3") //3 subject.subscribe { print(label: "1)", event: $0) }.addDisposableTo(disposeBag) //4 第二个订阅 subject.subscribe { print(label: "2)", event: $0) }.addDisposableTo(disposeBag) //5 subject.onNext("4") //6 subject.onError(MyError.anError) //7 subject.subscribe { print(label: "3)", event: $0) }.addDisposableTo(disposeBag) //8 subject.onNext("5") } 执行结果和分析: --- Example of: replay --- 1) 2 1) 3 2) 2 2) 3 1) 4 2) 4 1) anError 2) anError 3) 3 3) 4 3) anError 1:创建一个ReplaySubject,并制定缓冲区大小 2:为subject发送3个新消息 3:开始订阅观察者序列,一旦订阅将获得最新的两个元素,1被忽略了,因为缓冲区大小只能存储两个元素 4:添加第二个订阅者,将获得缓冲区的数据 5:添加新的元素到subject,那么会为之前的两个订阅者发送该消息 6:发送错误消息,终止了当前的观察者序列 7:添加新的订阅者,将获得最新的两个信息,3和4. 因为错误事件,输入终止了观察者序列,但是缓冲内容还在,所以添加新的订阅者,还是会由缓冲的数据向订阅者发送消息,然后由于出错终止,所以会发送错误信息。 8:观察者序列终止,发送消息无效
example(of: "Variable") { let disposeBag = DisposeBag() //1 var variable = Variable("Initial value") //2 variable.asObservable().subscribe { print(label: "1)", event: $0) }.addDisposableTo(disposeBag) //3 variable.value = "1" //4 variable.asObservable().subscribe { print(label: "2)", event: $0) }.addDisposableTo(disposeBag) //5 variable.value = "2" } 执行结果和分析: --- Example of: Variable --- 1) Initial value 1) 1 2) 1 1) 2 2) 2 1) completed 2) completed 1:初始化一个Variable实例,类型被自动推测 2:开始订阅观察者序列,首先调用asObservable()获得观察者序列然后开始订阅,立马接收到初始值消息 Initial value 3:发送新消息,订阅者将接受新消息1 4:添加新的订阅者,获得最新的元素值,那么就是消息1 5:新发送新消息,观察者序列将向两个订阅者发送消息,打印2个2,最后自动发送完成事件