先了解下Runloop的幾種模式棺牧,常用的有兩種,NSDefaultRunLoopMode 默認(rèn)模式、UITrackingRunLoopMode UI模式??、 NSRunLoopCommonModes? UI模式&默認(rèn)模式
而Runloop是一個(gè)運(yùn)行循環(huán)厢绝,負(fù)責(zé)監(jiān)聽事件,沒有事件發(fā)生時(shí)會(huì)進(jìn)入休眠狀態(tài)带猴,雖然他再一次循環(huán)中只處理一個(gè)事件昔汉,但他循環(huán)一次的時(shí)間非常短,所以當(dāng)他再一次循環(huán)中渲染界面的時(shí)候會(huì)chua的一下就完成了拴清。
再說說NSTimer 靶病,計(jì)時(shí)器是碼字過程中經(jīng)常會(huì)用到的会通,但是很多時(shí)候,對他的運(yùn)行機(jī)制了解的并不夠
咱先看下基本用法:
倘若將模式換成默認(rèn)娄周,會(huì)發(fā)生個(gè)面試?yán)仙U劦膯栴}涕侈,就是當(dāng)UI模式有事件需要響應(yīng)時(shí),RunLoop會(huì)切換到UI模式下完成相應(yīng)的事件操作煤辨,才會(huì)回到默認(rèn)模式下繼續(xù)執(zhí)行計(jì)時(shí)器操作裳涛,所以就牽出了NSTimer 的另一種用法
scheduledTimerWithTimeInterval會(huì)默認(rèn)執(zhí)行[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode],將其加到默認(rèn)模式下掷酗,倘若確定計(jì)時(shí)器下不會(huì)有UI事件產(chǎn)生调违,可以用這種方式
另外有一點(diǎn)需要注意的是雖然每個(gè)線程都會(huì)有自己的RunLoop窟哺,但是除了主線程外泻轰,其他線程的RunLoop都是默認(rèn)不開啟的,咱先來看一段代碼
可以發(fā)現(xiàn)且轨,當(dāng)前線程是新開的子線程浮声,但是計(jì)時(shí)器的卻并沒有像在主線程的中那樣重復(fù)執(zhí)行我們的timerAction方法,那是因?yàn)槲覀冏泳€程中的RunLoop是默認(rèn)不開啟的旋奢,他并不會(huì)像在主線程中那樣有運(yùn)行循環(huán)持續(xù)監(jiān)聽我們的計(jì)時(shí)器事件泳挥,解決辦法是需要我們手動(dòng)開啟當(dāng)前線程的RunLoop,像這樣
[[NSRunLoop currentRunLoop] run]讓當(dāng)前的RunLoop跑起來,那么問題來了至朗,run后面的代碼并沒有執(zhí)行屉符,其實(shí)是因?yàn)镽unLoop不僅僅是個(gè)運(yùn)行循環(huán),還是個(gè)特殊的死循環(huán)锹引,所以后面的語句并不會(huì)執(zhí)行矗钟,解決方法也很簡單,只需要給當(dāng)前的RunLoop一個(gè)循環(huán)時(shí)間就行了[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];