RxSwift学习笔记(2) -信号的形态

Subject的概念和简单创建


Subject起的作用类似于bridge或者proxy, 它同时扮演观察者和被观察者. 又能发送信号, 又能接收信号.

创建Subject

let subject = PublishSubject<String>()

//添加subscribe的closure
subject.subscribe({ (event) in
    //do sth
}).addDisposableTo(disposeBag)

//发送next
subject.onNext("🐶")

Subject的种类


ReplaySubject会在添加新的subscriber的时候给它发送之前的信号
let subject = ReplaySubject<String>.create(bufferSize: 1)

这里的bufferSize指的是发送最近的几个信号, 1就是只发送之前的一个.

BehaviourSubject相当于上一个bufferSize = 1.
let subject = BehaviorSubject(value: "🔴")

这样的设定比较适合那种一开始需要一个初始值的模块接收信号, 有一点需要注意的是, 所有的Subject都不会自己发送complete事件.

BehaviourSubject有一个Wrapper叫Variable, 和subject不同的是, 它在deinit的时候回自动发complete事件:

let variable = Variable("🔴")
variable.asObservable().addObserver("1").addDisposableTo(disposeBag)

合并Subject


StartWith

StartWith(:)用last-in-first-out规则, 插入信号.

Observable.of("🐶", "🐱", "🐭", "🐹")
    .startWith("1")
    .startWith("2")
    .startWith("3", "A", "B")
    .subscribeNext { print($0) }
    .addDisposableTo(disposeBag)

输出: 3, A, B, 2, 1, 🐶, 🐱, 🐭, 🐹

Merge

merge(: )把两个Subject合并:

Observable.of(subject1, subject2)
    .merge()

subscribe上merge()出来的Observable的话, 会同时接收到两个subject发出的信号, 相当于同时observable了subject1和subject2.

Zip

zip(:)让同样是组合信号, 但它是一种母信号集合为基础的组合.

Observable.zip(stringSubject, intSubject) { stringElement, intElement in
    return "\(stringElement) \(intElement)"
    }

subscribe了zip出来的信号的话, 接收到的是各个信号源从subscribe的时刻开始算起相同index的值组合的结果.

值得一提的是, 如果observable1发出了信号, observable2没发出, 那么zip出来的Observable并不会发出信号, 只有当observable2发出了, zip出来的Observable才会感应到并且往下派送信号.

我觉得这非常适合做那种异步集合操作, 比如说我要异步下载image1, image2, image3, 我需要系统在这三张图都下载好的时候给我发送一个提示, 用zip的话, 很方便就能拿到这样一个信号了.

CombineLatest

Combine类似Zip, 区别在它每次向下级发送信号的时候, 母Observable的值取最近的一个.

Observable.combineLatest(stringSubject, intSubject) { stringElement, intElement in
        "\(stringElement) \(intElement)"
    }

这种组合的应用场景我想到的有游戏里面的一些状态的刷新机制, Subject1之前的值都没有意义, 只要最新的值. 而Subject2一旦触发传递信号, 就会触发某个事件, 这个事件读取当前subject1和subject2的信息, 对应的就是往下一级发送信号.

combineLatest有一个Array的拓展:

let stringObservable = Observable.just("❤")
let fruitObservable = ["🍎", "🍐", "🍊"].toObservable()
let animalObservable = Observable.of("🐶", "🐱", "🐭", "🐹")

[stringObservable, fruitObservable, animalObservable].combineLatest {
        "\($0[0]) \($0[1]) \($0[2])"
    }
    .subscribeNext { print($0) }
    .addDisposableTo(disposeBag)

输出:

❤ 🍊 🐶
❤ 🍊 🐱
❤ 🍊 🐭
❤ 🍊 🐹

监听切换

添加这一行 switchLatest()
当Observable的内核变化的时候, 观察者自动切换监听的对象.

let disposeBag = DisposeBag()

let subject1 = BehaviorSubject(value: "⚽️")
let subject2 = BehaviorSubject(value: "🍎")

let variable = Variable(subject1)
    
variable.asObservable()
    .switchLatest()
    .subscribeNext { print($0) }
    .addDisposableTo(disposeBag)

subject1.onNext("🏈")
subject1.onNext("🏀")

variable.value = subject2

subject1.onNext("⚾️")

subject2.onNext("🍐")

输出:

⚽️
🏈
🏀
🍎
🍐

通过variable做这样的操作, 我想象之中是可以做偷换信号源的功能. 比如, 对某一个API, retrieve data的方式是一样的, 我没必要重新写一遍subscriber的实现代码, 偷换一下从服务器Fetch数据的信号源就可以了.

Referece:
https://github.com/ReactiveX/RxSwift/tree/master/Rx.playground
https://github.com/ReactiveX/RxSwift/tree/master/Documentation

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 发现 关注 消息 RxSwift入坑解读-你所需要知道的各种概念 沸沸腾关注 2016.11.27 19:11*字...
    枫叶1234阅读 2,713评论 0 2
  • 最近在学习RxSwift相关的内容,在这里记录一些基本的知识点,以便今后查阅。 Observable 在RxSwi...
    L_Zephyr阅读 1,700评论 1 4
  • 首先,何为RxSwift? RxSwift是ReactiveX的Swift版本,一个响应式变成框架。传送门 开始之...
    cocoawork丶阅读 441评论 0 3
  • 注:只包含标准包中的操作符,用于个人学习及备忘参考博客:http://blog.csdn.net/maplejaw...
    小白要超神阅读 2,142评论 2 8
  • 泛型Generic在swift中非常重要,它提升了代码的通用性和简洁性,很多开源的组件都是通过泛型来实现。泛型是什...
    flionel阅读 2,597评论 0 2