工作需要轩褐,粗略了解了ios上的幾種定時(shí)器椎咧。
NSTimer:
? ? ? ? ? ?這個(gè)底層怎么定時(shí)我不清楚,應(yīng)該是到了一定時(shí)間之后把介,向runLoop添加一個(gè)事件勤讽,這也就意味著蟋座,如果想在異步線程開(kāi)啟timer ,就需要手動(dòng)的將timer 添加到runLoop中脚牍,并且run起來(lái)向臀。
? ? ? ? ? ?網(wǎng)上看了一些說(shuō)的精確度,不是明白莫矗,親測(cè)過(guò),子線程創(chuàng)建一個(gè)timer砂缩,runLoop run起來(lái)作谚,只要timer里面的事件,不超過(guò)timer定時(shí)的時(shí)間庵芭,timer定時(shí)還是很準(zhǔn)確的妹懒,所以如果項(xiàng)目需要,timer里面的執(zhí)行事件的時(shí)間超過(guò)了定時(shí)器的時(shí)間双吆,就會(huì)出問(wèn)題了(試想一下眨唬,即使把事件再拿到另外一個(gè)線程去執(zhí)行,執(zhí)行時(shí)間永遠(yuǎn)都是大于定時(shí)時(shí)間的好乐,即使不影響定時(shí)時(shí)間匾竿,那么事件處理的堆積事件就會(huì)越來(lái)越多,肯定無(wú)法滿(mǎn)足需求蔚万,所以最好的是岭妖,將事件拆分,做成多個(gè)管道反璃,多個(gè)定時(shí)器昵慌,定時(shí)器時(shí)間大于處理定時(shí)器事件的時(shí)間)。我們通常說(shuō)的timer會(huì)出問(wèn)題淮蜈,我猜想可能是在主線程定義了一個(gè)timer斋攀,runloop執(zhí)行一個(gè)耗時(shí)很長(zhǎng)的循環(huán),錯(cuò)過(guò)了timer的周期梧田,這肯定會(huì)出問(wèn)題淳蔼,還有就是timer里面的事件處理時(shí)間不夠也會(huì)出問(wèn)題。所以我的解決辦法是裁眯,子線程runLoop run起來(lái)肖方,保持線程,同時(shí)保證timer里面的事件處理時(shí)間不超過(guò)timer時(shí)間未状,這樣就ok了俯画。
? ? ? ? ? 綜上所訴,用處理一般的事件完全足夠司草,只是使用中需要注意艰垂。
CADisplayLink:
? ? ? ? ? 這個(gè)是根據(jù)屏幕的幀率來(lái)發(fā)送事件泡仗,也依賴(lài)于runLoop,也就是說(shuō)猜憎,我們只能控制多少幀娩怎,觸發(fā)我們定義的事件,可用于界面的刷新胰柑,不能隨心所欲的控制時(shí)間截亦,不滿(mǎn)足我們一般的需求。使用也很簡(jiǎn)單柬讨,自行看API
GCD的source timer:
? ? ? 個(gè)人覺(jué)得這是比較給力(原諒我詞匯的匱乏)的一個(gè)定時(shí)器了崩瓤。原因如下,它不依賴(lài)于runLoop踩官,底層兩個(gè)隊(duì)列却桶,一個(gè)事件隊(duì)列,一個(gè)任務(wù)隊(duì)列蔗牡,定時(shí)到了之后颖系,從任務(wù)隊(duì)列里取出事件,加入到事件隊(duì)列(之前還有一步辩越,向任務(wù)隊(duì)列push任務(wù))嘁扼,執(zhí)行事件,至于他的一直執(zhí)行(為什么不依賴(lài)于runLoop黔攒,這于GCD的底層實(shí)現(xiàn)有關(guān)偷拔,有興趣可以自行了解),放到一個(gè)子線程執(zhí)行(想在主線程執(zhí)行的亏钩,可以用mainQUeue包一層)莲绰,在子線程的執(zhí)行順序也是串行的,所以如果block的執(zhí)行事件時(shí)間大于定時(shí)時(shí)間姑丑,還是會(huì)阻塞昵骤,可以一定層度上解決对碌,請(qǐng)看下面代
可以在block塊里再用一個(gè)隊(duì)列躲舌,異步執(zhí)行而账,包起來(lái),但是我們看一下執(zhí)行結(jié)果
確實(shí)留拾,執(zhí)行事件表面看并沒(méi)有影響定時(shí)器的定時(shí)戳晌,但是注意看始終都是系統(tǒng)分配的幾個(gè)線程去執(zhí)行事件,也就是說(shuō)這幾個(gè)線程是重復(fù)利用的痴柔,當(dāng)?shù)谝淮问褂猛曷儋耍诙问褂玫臅r(shí)候,定時(shí)并不準(zhǔn)確(可能是線程清理需要事件,具體不清楚)豪嚎,還有定時(shí)器的定時(shí)還是不準(zhǔn)確搔驼,這可能就跟GCDSource內(nèi)部實(shí)現(xiàn)有關(guān)系了,所以不推薦這樣使用侈询,目前我個(gè)人的想法就是舌涨,如果事件處理時(shí)間過(guò)長(zhǎng),要嗎想辦法拆分事件扔字,加管道囊嘉,加定時(shí)器,要嗎延長(zhǎng)定時(shí)時(shí)間革为。
與timer相比扭粱,的優(yōu)勢(shì)就是,不需要維持runLoop篷角,(性能消耗上或許有區(qū)別焊刹,沒(méi)有實(shí)際看過(guò))系任,還有本身就是子線程去執(zhí)行的恳蹲,不會(huì)阻塞主線程。
以上只是我個(gè)人的想法和總結(jié)俩滥,肯定有說(shuō)得不對(duì)的地方嘉蕾,希望多討論,多批評(píng)指正霜旧。