NSTimer導(dǎo)致誤差的原因

1.NSTimer加在main runloop中,模式是NSDefaultRunLoopMode,main負(fù)責(zé)所有主線程事件,例如UI界面的操作,復(fù)雜的運(yùn)算,這樣在同一個(gè)runloop中timer就會(huì)產(chǎn)生阻塞。

2.模式的改變。主線程的 RunLoop 里有兩個(gè)預(yù)置的 Mode:kCFRunLoopDefaultMode 和 UITrackingRunLoopMode。

當(dāng)你創(chuàng)建一個(gè) Timer 并加到 DefaultMode 時(shí),Timer 會(huì)得到重復(fù)回調(diào),但此時(shí)滑動(dòng)一個(gè)ScrollView時(shí),RunLoop 會(huì)將 mode 切換為 TrackingRunLoopMode,這時(shí) Timer 就不會(huì)被回調(diào),并且也不會(huì)影響到滑動(dòng)操作。所以就會(huì)影響到NSTimer不準(zhǔn)的情況。

PS:DefaultMode 是 App 平時(shí)所處的狀態(tài),rackingRunLoopMode 是追蹤 ScrollView 滑動(dòng)時(shí)的狀態(tài)。

解決的方法,

1.在主線程中進(jìn)行NSTimer操作,但是將NSTimer實(shí)例加到main runloop的特定mode(模式)中。避免被復(fù)雜運(yùn)算操作或者UI界面刷新所干擾。

self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(showTime) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

2.在子線程中進(jìn)行NSTimer的操作,再在主線程中修改UI界面顯示操作結(jié)果;


- (void)timerMethod2 {

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object:nil];

[thread start];

}

- (void)newThread

{

@autoreleasepool

{

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showTime) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] run];

}

}

總結(jié):

一開始的時(shí)候系統(tǒng)就為我們將主線程的main runloop隱式的啟動(dòng)了。在創(chuàng)建線程的時(shí)候,可以主動(dòng)獲取當(dāng)前線程的runloop。每個(gè)子線程對(duì)應(yīng)一個(gè)runloop

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容