在 iOS 開發中,我們經常會用到 計時器 這個類,用來進行一些重複或者延遲調用。
不過,在實際的使用中,如果你是用來週期地更新 UI,則會發現 計時器 的調用經常會被其他操作阻擋導致無法正常更新 UI。
比如說在我的 HourlyMeow 項目中,自定義時鐘界面要實現一個鐘錶供用戶對時,這個電子表我就是用 計時器 實現的,由於是精確到秒,那麼 的TableView 滾動的時候就無法正確更新。
根本原因
默認來說,我們添加的 計時器 就自動加入了當前 RunLoop 的默認模式,這個 RunLoop 自然也就是主線程的 RunLoop ,但接下來你拖拽屏幕就不行了,因為 RunLoop 模式切換了!它切換到了一個專門用來響應拖拽的模式裡,這樣一來,你的 計時器 自然就無法更新 UI 了。
顯然,這就是 計時器 阻擋主線程的根本原因,那麼我們只要想辦法把這個 計時器 也放到 RunLoop 的其他模式裡不就可以了。
但是很遺憾,同一時間,一個 RunLoop 只可以運行一個模式,如果要變,就只能切換。——沒錯,它只有一個“線程”!運行了這個模式,那另一個就要停下來。
commonModes 從名字你就可以看出,它是一個複數,這實際上並不是一個真正的 RunLoop 模式,實際上是多個模式的集合,我們將 計時器 放到這個模式裡,它也就在所有模式裡生效。這樣一來,無論你怎麼操作手機,切換哪個 RunLoop 模式, 計時器 也能正常調用了。
1 2 |
self.timer = Timer(timeInterval: 1, target: self, selector: #selector(updateTimeLabel), userInfo: nil, repeats: true) RunLoop.main.add(timer!, forMode: .commonModes) |
本文由 落格博客 原創撰寫:落格博客 » Timer 無法在拖動時更新 UI
轉載請保留出處和原文鏈接:https://www.logcg.com/archives/3046.html