1. 程式人生 > >Combine 框架,從0到1 —— 4.在 Combine 中使用 KVO

Combine 框架,從0到1 —— 4.在 Combine 中使用 KVO

  本文首發於 [Ficow Shen's Blog](https://ficowshen.com),原文地址: [Combine 框架,從0到1 —— 4.在 Combine 中使用 KVO](https://blog.ficowshen.com/page/post/17)。   ## 內容概覽 - 前言 - 用 `KVO` 監控改動 - 將 `KVO` 程式碼遷移到 `Combine` - 總結   ## 前言   `KVO`([Key-Value Observing](Using Key-Value Observing in Swift)) 是蘋果開發者常用的功能,很多框架都會使用 `KVO` 來發送非同步改動。將基於回撥和閉包的 `KVO` 程式碼遷移到 `Combine`,可以使你的程式碼更優雅、更易維護。   ## 用 KVO 監控改動   在下面的示例中, `UserInfo` 型別為它的 `lastLogin` 屬性提供了 `KVO` 支援。示例程式碼在 `viewDidLoad()` 方法中呼叫了 `observe(_:options:changeHandler:)` 方法來建立了一個處理這個屬性的變動的閉包。這個閉包接收一個描述了改動事件的 `NSKeyValueObservedChange` 物件,並從這個物件取出了 `newValue` 屬性的值,然後列印。 接下來,示例程式碼在 `viewDidAppear(_:)` 方法中改了 `lastLogin` 屬性的值,最終觸發了閉包並列印了訊息。 ``` swift class UserInfo: NSObject { @objc dynamic var lastLogin: Date = Date(timeIntervalSince1970: 0) } @objc var userInfo = UserInfo() var observation: NSKeyValueObservation? override func viewDidLoad() { super.viewDidLoad() observation = observe(\.userInfo.lastLogin, options: [.new]) { object, change in print ("lastLogin now \(change.newValue!).") } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) userInfo.lastLogin = Date() } ```   ## 將 KVO 程式碼遷移到 Combine   想要遷移 `KVO` 程式碼到 `Combine`,只需替換 `observe(_:options:changeHandler:)` 方法為 `NSObject.KeyValueObservingPublisher`。您可以通過在父物件(parent object)上呼叫 `publisher(for:)` 方法來獲得此釋出者的例項,如以下示例的 `viewDidLoad()` 方法所示: ``` swift class UserInfo: NSObject { @objc dynamic var lastLogin: Date = Date(timeIntervalSince1970: 0) } @objc var userInfo = UserInfo() var cancellable: Cancellable? override func viewDidLoad() { super.viewDidLoad() cancellable = userInfo.publisher(for: \.lastLogin) .sink() { date in print ("lastLogin now \(date).") } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) userInfo.lastLogin = Date() } ``` `KVO釋出者` 會生成觀察型別的元素(在本例中為 `Date`),而不是 `NSKeyValueObservedChange`。這樣就節省了一步操作,因為你不必像前一個示例中那樣從 `change` 物件中獲取 `newValue`。   ## 總結   如果上面的示例變得更加複雜,傳統的 `KVO` 程式碼可能會變得非常臃腫,而基於 `Combine` 的 `KVO` 程式碼可以利用各種操作符進行鏈式呼叫。這樣,就可以讓程式碼更優雅,同時保持程式碼的易讀性。對於以後維護這段程式碼的人來說,這將是一種辛福的感覺~