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  也能正常调用了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

42 − = 33