Timer 无法在拖动时更新 UI

在 iOS 开发中我们经常会用到 Timer 这个类用来进行一些重复或者延迟调用

不過,在实际的使用中如果你是用来周期地更新 UI则会发现 Timer 的调用经常会被其他操作阻挡导致无法正常更新 UI

比如说在我的 HourlyMeow 项目中自定义时钟界面要实现一个钟表供用户对时这个电子表我就是用 Timer 實現的,由于是精确到秒,那麼 的TableView 滚动的时候就无法正确更新

根本原因

默認來說,我们添加的 Timer 就自动加入了当前 RunLoop 的默认模式,這個 RunLoop 自然也就是主线程的 RunLoop但接下来你拖拽屏幕就不行了,因為 RunLoop 模式切换了!它切换到了一个专门用来响应拖拽的模式里,這樣一來,你的 Timer 自然就无法更新 UI 了

顯然,這就是 Timer 阻挡主线程的根本原因那么我们只要想办法把这个 Timer 也放到 RunLoop 的其他模式里不就可以了

但是很遺憾,同一时间,一個 RunLoop 只可以运行一个模式如果要变就只能切换。——沒錯,它只有一个“线程”!运行了这个模式那另一个就要停下来

commonModes 从名字你就可以看出它是一个复数这实际上并不是一个真正的 RunLoop 模式,实际上是多个模式的集合我们将 Timer 放到这个模式里它也就在所有模式里生效。這樣一來,无论你怎么操作手机切换哪个 RunLoop 模式, Timer 也能正常调用了

發表評論

您的電子郵件地址不會被公開. 必填字段標 *

− 1 = 3