Combine(一) Publisher和Subscriber

1、Publisher被观察者

Publisher是一个protocol,是Combine的核心;publisher可以向他的subscriber发送一个或多个values直到它发送了一个completion时间,这个completion可以是正常的结束,也可以是一个error。我们可以很简单的用一个array来创建一个publisher:

let publisher = (1...5).publisher // b
publisher.sink(receiveCompletion: { _ in // a
    print("completed")
}, receiveValue: { val in
    print("value: \(val)")
})
// 输出
value: 1
value: 2
value: 3
value: 4
value: 5
completed

a) .sink和.assign是两个为publisher绑定观察者的方法,观察者就像例子中的一样,是简单的closures来handle publisher发送出的值和结束事件。
b) 用array创建出的publisher会将array中的元素一个一个的发送给观察者然后结束。注意:publisher只有在有观察者的情况下才会开始发送value

而在上一篇文章中的Just就是一个特殊的Publisher,他只会发送一次然后自动结束

let just = Just("Hello shit")
just.sink(receiveCompletion: {
    _ in
    print("completed 111")
}, receiveValue: {
    val in
    print("\(val) 111")
})

just.sink(receiveCompletion: {
    _ in
    print("completed222")
}, receiveValue: {
    val in
    print("\(val) 222")
})
// 输出
Hello shit 111
completed 111
Hello shit 222
completed222

2、Subject

Subject也可以理解成特殊的Publisher,不同于publisher,subject可以用.send()来想subscriber发送values。先介绍两种常用的subjects:

  • PassthroughSubject - 可以持续向subscriber传输值或者结束事件,可以没有初始值
  • CurrentValueSubject - 初始化时必须有初始值,可以通过subject.value来查看当前publisher发送的值

看完Subscriber一起给栗子

3、Subscriber观察者

上面的两个例子都是用了sink绑定了closures来作为观察者, 如果我们要自己定义subscriber,那就得遵循Subscriber protocol:

class MySubscriber: Subscriber {
    typealias Input = Int // a
    typealias Failure = MyError // b

    func receive(completion: Subscribers.Completion<MyError>) { // c
        print("received completion")
    }

    func receive(_ input: Int) -> Subscribers.Demand { // d
        print("received value: \(input)")
        switch input {
        case 1:
            return .max(1) // e
        default:
            return .none // f
        }
    }

    func receive(subscription: Subscription) { // g
        subscription.request(.max(2)) // h
        print("subscription received")
    }
}

a) 接受的类型,这个必须和publisher的输出类型相等才行
b) 错误类型,也需要和publisher会发出的error类型一样
c) 当接收到publisher发出的结束事件之后要做的
d) 当接收到publisher发出的值的时候要做的,注意这里返回了一个Subscribers.Demand意思是最多还能接受多少个values
e) 把最多能接受values的个数+1
f) 最多能接受values的个数不变
g) 当订阅了publisher的时候执行,subscription.request可以定义初始接受values的个数

let publisher = PassthroughSubject<Int, MyError>()
let subscriber = MySubscriber()
publisher.subscribe(subscriber)

publisher.send(3)
publisher.send(1)
publisher.send(5)
publisher.send(6)
publisher.send(completion: .finished)
//输出
subscription received
received value: 3
received value: 1
received value: 5
received completion

为啥没输出6呢?回去看看MySubscriber的定义就明白了

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

推荐阅读更多精彩内容