Swift — Combine Subject & sink & assign

讓我們看看 Combine 中的 Subject 以及 sink、assign 的用法吧!

Jeremy Xue
Jeremy Xue ‘s Blog
5 min readAug 9, 2020

--

在 Combine 中除了 Publisher、Subscriber 和 Opearator 三個重要的角色之外,這次再來介紹幾個我們也會在 Combine 中經常會碰到的重要角色 Subject,以及 Publisher 中簡單連結訂閱者的兩個方法 sink 以及 assign

摘要:

  • Subject
  • CurrentValueSubject
  • PassthroughSubject
  • sink(receiveCompletion: receiveValue:)
  • assign(to:)

✒︎ Subject

暴露一個方法給外部調用者來發布元素的發布者。

Subject 是一種 Publisher,你可以調用其 send(_:) 方法將值 “注入” 到數據流中,對於現有命令式程式碼適應 Combine 模型很有用。

✒︎ CurrentValueSubject

一個包裝單個值並在值變更時發布新元素的主題(Subject)。

PassthroughSubject 不同,CurrentValueSubject 維護最近發布元素的緩衝區。在 CurrentValueSubject 上調用 send(_:) 也會更新當前值,使其等效於直接更新該值。

✒︎ PassthroughSubject

向下游訂閱者廣播元素的主題。

作為 Subject 的具體實現,PassthroughSubject 提供了一種便利方式來使現有命令式程式碼適應 Combine 模型。

CurrentValueSubject 不同,PassthroughSubject 沒有初始值或最新發布元素元素的緩衝區。如果沒有訂閱者,或當前需求為零,則 PassthrougnSubject 會丟棄值。

✒︎ sink(receiveCompletion:receiveValue:)

為訂閱者連結基於閉包的行為。

參數:

  • receiveComplete: 在完成時執行的閉包。
  • receiveValue: 在收到值時執行的閉包。

返回值:

為一個可取消實例,在結束分配接收值使用。結果的取消分配將拆除(tear down)訂閱數據流。

使用 sink(receiveCompletion:receiveValue:) 來觀察發布者收到的值,並且使用你指定的閉包對其進行處理。

在此範例中,Range 發布者將整數發布到 sink(receiveCompletion:receiveValue:) 運算符的 receiveValue 閉包中,該閉包將其打印到控制台中。完成接收器 sink(receiveCompletion:receiveValue:) 運算符的 receiveCompletion 閉包表示數據流成功終止。

此方法創建訂閱者並且在返回訂閱者之前立即請求無限數量的值,返回值應該被保留,否則數據流將被取消。

✒︎ assign(to:on:)

將來自發布者的每個元素分配給對象中的屬性。

當 Failure 為 Never 時可用。

參數:

  • keyPath:表示要分配屬性的 keyPath。關於 Key-Path 表達式請參考此官方文章
  • object:包含此屬性的對象。訂閱者在每次接收到新值時都會分配給該對象的屬性。

返回值:

一個 AnyCancellable 實例。當你不再想要發布者分配屬性時,請在此實例上調用 cancel()。返初始化此實例也將取消自動分配。

當你想要發布者每次產生值的時候都設置給給定的屬性時,請使用 assign(to:on:) 訂閱者。

在此範例中,assign(to:on:) 設置在 MyClass 實例上的 anInt 屬性:

重要:由此運算符所創建的 Subscribers.Assign 實例維護對對象的強引用,並且在上游發布者完成時(正常或有錯誤時)將設置其為 nil。

--

--

Jeremy Xue
Jeremy Xue ‘s Blog

Hi, I’m Jeremy. [好想工作室 — iOS Developer]