?
本文首發(fā)于 Ficow Shen's Blog,原文地址: Combine 框架吧雹,從0到1 —— 4.在 Combine 中使用計時器。
?
內容概覽
- 前言
- 使用計時器執(zhí)行周期性的工作
- 將計時器轉換為計時器發(fā)布者(
Timer.TimerPublisher
) - 總結
?
前言
?
計時器是蘋果開發(fā)者常用的功能涂身。如果你的應用使用 Foundation
框架中的計時器 Timer
來周期性地執(zhí)行某些操作,你可以用 Combine
簡化這些代碼搓蚪。
現(xiàn)在蛤售,讓我們來學習如何使用 Combine
處理計時器,并將已有的計時器處理代碼遷移到 Combine
妒潭。
?
使用計時器執(zhí)行周期性的工作
?
對于 iOS
開發(fā)人員而言悴能,以下代碼一定非常眼熟:
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
self.myDispatchQueue.async() {
self.myDataModel.lastUpdated = Date()
}
}
}
以上代碼使用 scheduledTimer(withTimeInterval:repeats:block:)
來實現(xiàn)每秒鐘在 myDispatchQueue
中更新 self.myDataModel.lastUpdated
的功能。
?
將計時器轉換為計時器發(fā)布者(Timer.TimerPublisher
)
?
要將以上代碼遷移到 Combine
雳灾,只需將 Timer
(scheduledTimer(withTimeInterval:repeats:block:)
的返回值) 替換為 Timer.TimerPublisher
漠酿。調用 Timer. publish(every:tolerance:on:in:options:)
方法即可創(chuàng)建一個發(fā)布者。
每次底層的計時器(Timer
)觸發(fā)時谎亩,發(fā)布者都會發(fā)出一個新的日期(Date
)實例炒嘲,該日期代表計時器觸發(fā)的瞬間。然后匈庭,你可以將 Combine
操作符應用到這個日期實例上夫凸,最終將這個發(fā)布者和一個訂閱者(如:sink(receiveValue:)
或 assign(to:on:)
)連接。
?
由于
Timer.TimerPublisher
遵從ConnectablePublisher
協(xié)議阱持,因此在您顯式地連接之前夭拌,它不會產(chǎn)生任何元素。為此衷咽,可以通過手動調用connect()
或使用autoconnect()
運算符在訂閱者連接時自動連接來實現(xiàn)鸽扁。關于ConnectablePublisher
的用法,可以參考 這篇文章镶骗。
?
下一個示例將展示如何使用 Timer.TimerPublisher
替換上一個示例桶现。它使用 Combine
的操作符來完成上一個示例中的閉包中的操作:
var cancellable: Cancellable?
override func viewDidLoad() {
super.viewDidLoad()
cancellable = Timer.publish(every: 1, on: .main, in: .default)
.autoconnect()
.receive(on: myDispatchQueue)
.assign(to: \.lastUpdated, on: myDataModel)
}
在這個例子中,Combine
操作符替換了上一個示例的閉包中的所有行為:
-
receive(on:options:)
操作符確保了后續(xù)操作在指定的調度隊列中執(zhí)行卖词,它替代了前面用到的async()
調用巩那; -
assign(to:on:)
操作符通過鍵路徑來更新數(shù)據(jù)模型的lastUpdated
屬性吏夯;
?
使用 Combine
來簡化你的代碼時,你會發(fā)現(xiàn) Timer.TimerPublisher
會產(chǎn)生新的 Date
實例作為其輸出類型即横。而第一個示例的閉包是將 Timer
本身作為其參數(shù)噪生,因此它必須手動創(chuàng)建新的 Date
實例。
?
總結
?
使用 Combine
來簡化你的計時器代碼時东囚,你會發(fā)現(xiàn):
- 代碼易讀性明顯提升跺嗽;
- 線程切換變得更簡單;
- 數(shù)據(jù)模型的更新可以通過鍵路徑(
key path
)來簡化页藻;
朋友桨嫁,行動起來吧!把現(xiàn)有項目中的舊代碼重構成使用 Combine
的代碼~
?
推薦繼續(xù)閱讀:Combine 框架份帐,從0到1 —— 4.在 Combine 中使用 KVO
?
本文內容來源:
Replacing Foundation Timers with Timer Publishers
?