Publisher
- 發布源協議,可以實現該協議來實現自己的數據
源
,
-
Subject
繼承自Publisher
,提供了三套默認的內置實現類
- 容器包裝類,具體實現交由
Subscriber
實現類來轉發數據流
- 內置提供各種各樣的操作符(函數式編程的仿函數,Swift語言的
Operator
)
- allSatisfy
- tryAllSatisfy
- compactMap
- contains
- filter
- tryFilter
- throttle
- ....等等
-
Publisher
接口
public protocol Publisher {
/// 數據輸出流,相當于訂閱者的數據輸入流
associatedtype Output
/// 數據發布,要么發布一個真實數據流,要么發布一個錯誤(或者可以選擇丟棄錯誤, Never忽略錯誤)
associatedtype Failure: Error
/// 接收數據源輸入流,并轉發給訂閱者
func receive<Subscriber: OpenCombine.Subscriber>(subscriber: Subscriber) where Failure == Subscriber.Failure, Output == Subscriber.Input
}
- 所有的操作符的流程都類似,追蹤一個操作符的調用順序和觸發流程
- 定義一個數組的數據流
[1, 2, 10000].publisher
, publisher
是Sequence
的一個擴展,內部使用Publishers.Sequence
進行了包裝成了一個可以被觀察的數據流
extension Sequence {
public var publisher: Publishers.Sequence<Self, Never> {
return .init(sequence: self)
}
- `Publishers.Sequence` 內部實現
/// 序列流繼承于`Publisher`
public struct Sequence<Elements: Swift.Sequence, Failure: Error>: Publisher {
/// 輸出源
public typealias Output = Elements.Element
public let sequence: Elements
public init(sequence: Elements) {
self.sequence = sequence
}
/// 實現 `Publisher`協議方法`receive`
public func receive<Downstream: Subscriber>(subscriber: Downstream)
where Failure == Downstream.Failure,
Elements.Element == Downstream.Input
{
/// 包裝類`Inner`實現了`Subscription`協議,內部持有當前收到的`subscriber`, 進行轉發
let inner = Inner(downstream: subscriber, sequence: sequence)
/// 判斷是否序列是否到末尾,如果序列結束發送完成事件并取消序列,數據流完成,反之,持續接收數據流
if inner.isExhausted {
subscriber.receive(subscription: Subscriptions.empty)
subscriber.receive(completion: .finished)
inner.cancel()
} else {
/// 內部會調用`Subscription`協議的 `request`方法
subscriber.receive(subscription: inner)
}
}
}
-
Inner
作為一個私有類,單獨實現了序列數據流的內部數據源的流轉(每一個操作符都有一套內部特有的Inner實現類),源碼我進行了部分簡化
private final class Inner<Downstream: Subscriber, Elements: Sequence, Failure>
: Subscription
where Downstream.Input == Elements.Element,
Downstream.Failure == Failure
{
typealias Iterator = Elements.Iterator
typealias Element = Elements.Element
private var sequence: Elements?
private var downstream: Downstream?
private var iterator: Iterator
private var next: Element?
private var pendingDemand = Subscribers.Demand.none
/// 初始化持有的`downstream`數據流,方便后續數據流轉
fileprivate init(downstream: Downstream, sequence: Elements) {
self.sequence = sequence
self.downstream = downstream
self.iterator = sequence.makeIterator()
next = iterator.next()
}
func request(_ demand: Subscribers.Demand) {
guard downstream != nil else {
return
}
while let downstream = self.downstream, pendingDemand > 0 {
if let current = self.next {
/// 迭代數據流,依次進行數據的轉發,交給訂閱者接收
let additionalDemand = downstream.receive(current)
}
if next == nil {
self.downstream = nil
self.sequence = nil
/// 序列結束,發送完成事件
downstream.receive(completion: .finished)
return
}
}
}
}
- 上面定義了數據流源,并發出了數據,等待訂閱者監聽數據流,
sink
和assign
操作符可以進行訂閱,后續會列出sink和assign的源碼
代碼演示片段
class Root: NSObject {
var name: String = ""
}
let root = Root()
let arr: [Int] = [1, 2, 100]
/// 將數組轉換成一個數據流
arr.publisher
/// 過濾數據流中大于2的元素
.filter{$0 > 2}
/// 進行一次轉換,轉成String類型
.compactMap{"\($0)"}
/// `Sink`訂閱數據源
.sink { value in
debugPrint("數據流: \(value)")
}.store(in: &cancel)
/// 使用keypath進行賦值
arr.publisher
.filter{$0 > 2}
.compactMap{"\($0)"}
/// `Assign` keypath 賦值
.assign(to: \.name, on: root).store(in: &cancel)
debugPrint("root name: \(root.name)")
/// 控制臺輸出
"數據流: 100"
"root name: 100"
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。