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) { // 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()
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的定义就明白了