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

 

本文首發於 Ficow Shen’s Blog,原文地址: Combine 框架,從0到1 —— 4.在 Combine 中使用 KVO

 

內容概覽

  • 前言
  • 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 屬性的值,最終觸發了閉包並列印了消息。

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() 方法所示:

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 程式碼可能會變得非常臃腫,而基於 CombineKVO 程式碼可以利用各種操作符進行鏈式調用。這樣,就可以讓程式碼更優雅,同時保持程式碼的易讀性。對於以後維護這段程式碼的人來說,這將是一種辛福的感覺~ 😉

朋友,行動起來吧!把現有項目中的舊程式碼重構成使用 Combine 的程式碼~

 

本文內容來源:
Performing Key-Value Observing with Combine

 

Tags: