從字面的意思看,runloop有循環(huán),跑圈的意思
runloop在開發(fā)中的作用是能夠保持程序的持續(xù)運(yùn)行,用于處理APP中的各種事件(比如觸摸事件否彩、定時(shí)器事件、selector事件)節(jié)省CPU資源嗦随,提高程序性能:該做事時(shí)做事列荔,該休息時(shí)休息
如果沒有runloop,
int main(int argc, char * argv[]) {
NSLog(@"execute main function");
return 0;//程序在此處就已經(jīng)結(jié)束了
}
而有runloop時(shí)枚尼,
int main(int argc, char * argv[]) {
BOOL running = YES;
do {
// 執(zhí)行各種任務(wù)贴浙,處理各種事件
// ......
} while (running);
return 0;
}//由于main函數(shù)里面啟動(dòng)了個(gè)RunLoop,所以程序并不會(huì)馬上退出署恍,保持持續(xù)運(yùn)行狀態(tài)
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
代碼的UIApplicationMain函數(shù)內(nèi)部就啟動(dòng)了一個(gè)RunLoop
所以UIApplicationMain函數(shù)一直沒有返回崎溃,保持了程序的持續(xù)運(yùn)行
這個(gè)默認(rèn)啟動(dòng)的RunLoop是跟主線程相關(guān)聯(lián)的
iOS中有2套API來訪問和使用RunLoop
Foundation
NSRunLoop
Core Foundation
CFRunLoopRef
NSRunLoop和CFRunLoopRef都代表著RunLoop對(duì)象
NSRunLoop是基于CFRunLoopRef的一層OC包裝,所以要了解RunLoop內(nèi)部結(jié)構(gòu)盯质,需要多研究CFRunLoopRef層面的API(Core Foundation層面)
runloop和線程的關(guān)系
每條線程都有唯一的一個(gè)與之對(duì)應(yīng)的RunLoop對(duì)象
主線程的RunLoop已經(jīng)自動(dòng)創(chuàng)建好了笨奠,子線程的RunLoop需要主動(dòng)創(chuàng)建
RunLoop在第一次獲取時(shí)創(chuàng)建,在線程結(jié)束時(shí)銷毀
在Foundation中獲Runloop
[NSRunLoop currentRunLoop]; // 獲得當(dāng)前線程的RunLoop對(duì)象
[NSRunLoop mainRunLoop]; // 獲得主線程的RunLoop對(duì)象
Core Foundation
CFRunLoopGetCurrent(); // 獲得當(dāng)前線程的RunLoop對(duì)象
CFRunLoopGetMain(); // 獲得主線程的RunLoop對(duì)象
在開發(fā)中如何使用RunLoop唤殴?什么應(yīng)用場景?
開啟一個(gè)常駐線程(讓一個(gè)子線程不進(jìn)入消亡狀態(tài)到腥,等待其他線程發(fā)來消息朵逝,處理其他事件)
在子線程中開啟一個(gè)定時(shí)器
在子線程中進(jìn)行一些長期監(jiān)控
可以控制定時(shí)器在特定模式下執(zhí)行
可以讓某些事件(行為、任務(wù))在特定模式下執(zhí)行
可以添加Observer監(jiān)聽RunLoop的狀態(tài)乡范,比如監(jiān)聽點(diǎn)擊事件的處理(在所有點(diǎn)擊事件之前做一些事情)
自動(dòng)釋放池什么時(shí)候釋放配名?
通過Observer監(jiān)聽RunLoop的狀態(tài),一旦監(jiān)聽到RunLoop即將進(jìn)入睡眠等待狀態(tài)晋辆,就釋放自動(dòng)釋放池(kCFRunLoopBeforeWaiting)
runloop的總結(jié)
其實(shí)它內(nèi)部就是do-while循環(huán)渠脉,在這個(gè)循環(huán)內(nèi)部不斷地處理各種任務(wù)(比如Source、Timer瓶佳、Observer)
一個(gè)線程對(duì)應(yīng)一個(gè)RunLoop芋膘,主線程的RunLoop默認(rèn)已經(jīng)啟動(dòng),子線程的RunLoop得手動(dòng)啟動(dòng)(調(diào)用run方法)
RunLoop只能選擇一個(gè)Mode啟動(dòng)霸饲,如果當(dāng)前Mode中沒有任何Source(Sources0为朋、Sources1)、Timer厚脉,那么就直接退出RunLoop