runloop是iOS底層機(jī)制中保持我們的程序一直運(yùn)行的機(jī)制旁瘫。他可以讓線程一直循環(huán)不退出。而在我們正常的編程中握爷。線程其實(shí)是線性的,當(dāng)線程處理完我們的代碼以后就自動(dòng)退出了襟交。runloop就是保證我們的應(yīng)用程序在沒有人操縱的情況下也能一直運(yùn)行的一種機(jī)制。
當(dāng)用戶打開我們的APP時(shí)伤靠,首先系統(tǒng)會(huì)初始化我們的APP捣域。我們知道Objective-c語(yǔ)言其實(shí)是C語(yǔ)言的擴(kuò)充。也就是說(shuō)他與C語(yǔ)言一樣是以main函數(shù)作為程序的入口宴合。我們創(chuàng)建一個(gè)工程時(shí)會(huì)在main文件中發(fā)現(xiàn)這樣的代碼
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
這是我們應(yīng)用程序的入口焕梅。其中UIApplicationMain就自動(dòng)的為我們的主線程啟動(dòng)了RunLoop。
當(dāng)應(yīng)用啟動(dòng)了之后形纺,如果用戶進(jìn)行了操作丘侠,則處理用戶的事件。如果用戶沒有進(jìn)行任何操作逐样,則主線程進(jìn)行等待。直到程序退出打肝。
而對(duì)于其他的線程來(lái)說(shuō)脂新,runloop并不是默認(rèn)啟動(dòng)的。需要我們顯式的調(diào)用他
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
每一個(gè)線程的RunLoop是唯一的争便,如果我們不自己創(chuàng)建他的話就永遠(yuǎn)不會(huì)被創(chuàng)建断医。
值得一提的是在iOS/OSX中提供了兩個(gè)RunLoop對(duì)象:
- CFRunLoopRef 是在 CoreFoundation 框架內(nèi)的,它提供了純 C 函數(shù)的 API鉴嗤,所有這些 API 都是線程安全的。
- NSRunLoop 是基于 CFRunLoopRef 的封裝醉锅,提供了面向?qū)ο蟮?API,但是這些 API 不是線程安全的垄琐。
也就是說(shuō)我們不能在一個(gè)進(jìn)程中操作另一個(gè)進(jìn)程的RunLoop经柴,這樣會(huì)造成意想不到的后果。但是我們卻可以獲取到NSRunLoop的CFRunLoopRef對(duì)象翻擒,來(lái)達(dá)到線程安全的目的:
- (CFRunLoopRef)getCFRunLoop;
NSRunLoop中有五個(gè)Mode:
- kCFRunLoopDefaultMode: 默認(rèn) mode,通常主線程在這個(gè) Mode 下運(yùn)行韭寸。
- UITrackingRunLoopMode: 追蹤mode恩伺,保證Scrollview滑動(dòng)順暢不受其他 mode 影響。
- UIInitializationRunLoopMode: 啟動(dòng)程序后的過渡mode晶渠,啟動(dòng)完成后就不再使用。
- GSEventReceiveRunLoopMode: Graphic相關(guān)事件的mode便瑟,通常用不到番川。
- kCFRunLoopCommonModes: 占位mode颁督,作為標(biāo)記DefaultMode和CommonMode用。
在runloop中不同的事件處理會(huì)切換到不同的mode下運(yùn)行沉御。
當(dāng)我們?cè)诨瑒?dòng)一個(gè)View時(shí),runloop會(huì)切換到trackingMode下運(yùn)行伐谈。這時(shí)候就會(huì)發(fā)生一些我們不希望發(fā)生的事情诵棵。比如我們使用了一個(gè)計(jì)時(shí)器。是默認(rèn)在default下運(yùn)行的非春。這時(shí)候當(dāng)我們滑動(dòng)一個(gè)View時(shí)缓屠,比如ScrollView敌完。計(jì)時(shí)器就會(huì)暫停。因?yàn)檫@時(shí)候runloop已經(jīng)切換到TrackingMode下了什湘。
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode: NSRunLoopCommonModes];
forMode的參數(shù)有兩種類型可供選擇: NSDefaultRunLoopMode 长赞, NSRunLoopCommonModes得哆。
NSRunLoopCommonModes 能夠在多線程中起作用贩据,這個(gè)模式等效于NSDefaultRunLoopMode和NSEventTrackingRunLoopMode的結(jié)合闸餐,這也是將modes換為NSRunLoopCommonModes便可解決的原因。