之前做過的一些項目中有這樣的一種情況,我們當時是做一個秒殺活動,要求在頁面中顯示活動的倒計時,我是通過+scheduledTimerWithTimeInterval出發timer的方式做的,但是發現一個很奇怪的現象,就是當我滑動列表的時候,timer暫停了,頁面中的倒計時停止了。
后來通過深入研究NSTimer的運行原理,才發現NSTimer與RunLoop有關(其實RunLoop與線程是緊密相關的,這里就不做多說了),RunLoop只能運行在一種mode下,如果要換mode,當前的loop也需要停下重啟成新的。利用這個機制,ScrollView滾動過程中NSDefaultRunLoopMode(kCFRunLoopDefaultMode)的mode會切換到UITrackingRunLoopMode來保證ScrollView的流暢滑動;只有在NSDefaultRunLoopMode模式下處理的事件會影響scrllView的滑動。
如果我們把一個NSTimer對象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主運行循環中的時候, ScrollView滾動過程中會因為mode的切換,而導致NSTimer將不再被調度。
但是因為mode還是可定制的,所以:Timer計時會被scrollView的滑動影響的問題可以通過將timer添加到NSRunLoopCommonModes(kCFRunLoopCommonModes)來解決。代碼如下:
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
target:self
selector:@selector(timerTick:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
