-
每一個(gè)程序入口的mian函數(shù)就有一個(gè)RunLoop啤它。
UIApplicationMain函數(shù)內(nèi)部啟動(dòng)的一個(gè)RunLoo,所以UIApplicationMain函數(shù)一直沒(méi)有返回鸿摇,這樣就保持了程序的持續(xù)運(yùn)行(這個(gè)RunLoop是相關(guān)聯(lián)主線程的)
代碼:
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv,nil,NSStringFromClass([AppDelegate class]));
}
}
什么是RunLoop
- 運(yùn)行循環(huán)
- 基本作用:
1.保持程序的持續(xù)運(yùn)行,如果沒(méi)有RunLoop痴颊,程序執(zhí)行完main函數(shù)就結(jié)束了米辐。
2.處理App中的各種事件(比如觸摸事件、定時(shí)器事件公条、Selector事件)
3.節(jié)省CPU資源,提高程序性能:該做事時(shí)做事隔披,該休息時(shí)休息
RunLoop與線程間的關(guān)系
1.每一個(gè)RunLoop對(duì)象都有一個(gè)線程和它唯一對(duì)應(yīng)赃份。
2.主線程的RunLoop是自動(dòng)創(chuàng)建的,子線程的RunLoop需要主動(dòng)創(chuàng)建奢米。
3.RunLoop是在第一次獲取的時(shí)候創(chuàng)建抓韩,并在線程結(jié)束時(shí)自動(dòng)銷毀。
iOS中有2個(gè)API可以提供訪問(wèn)和使用RunLoop
- Foundation : NSRunLoop
[NSRunLoop currentRunLoop];// 獲得當(dāng)前線程的RunLoop對(duì)象
[NSRunLoop mainRunLoop];// 獲得主線程的RunLoop對(duì)象 - CoreFoundation : CFRunLoopRef
CFRunLoopGetCurrent();// 獲得當(dāng)前線程的RunLoop對(duì)象
CFRunLoopGetMain();// 獲得主線程的RunLoop對(duì)象
RunLoop相關(guān)類
- CFRunLoopRef
- CFRunLoopModeRef
- CFRunLoopSourceRef
- CFRunLoopTimerRef
- CFRunLoopObserverRef
1.CFRunLoopModeRef
- CFRunLoopModeRef代表RunLoop的運(yùn)行模式
- 一個(gè) RunLoop包含若干個(gè) Mode鬓长,每個(gè)Mode又包含若干個(gè) Source/Timer/Observer
- 每次RunLoop啟動(dòng)時(shí)谒拴,只能指定其中一個(gè) Mode,這個(gè)Mode被稱 作 CurrentMode
- 如果需要切換Mode涉波,只能退出Loop英上,再重新指定一個(gè)Mode進(jìn)入,這樣做主要是為了分隔開(kāi)不同組的Source/Timer/Observer,讓其互不影響
2.CFRunLoopTimerRef
- CFRunLoopTimerRef是基于時(shí)間的觸發(fā)器
- CFRunLoopTimerRef基本上說(shuō)的就是NSTimer啤覆,它受RunLoop的Mode影響
3.CFRunLoopSourceRef
- CFRunLoopSourceRef是事件源(輸入源)
4.CFRunLoopObserverRef
- CFRunLoopObserverRef是觀察者,能夠監(jiān)聽(tīng)RunLoop的狀態(tài)改變
添加觀察者的代碼:
//創(chuàng)建observer
CFRunLoopObserverRefobserver = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(),kCFRunLoopAllActivities,YES,0,^(CFRunLoopObserverRefobserver, CFRunLoopActivityactivity) {
NSLog(@"----監(jiān)聽(tīng)到RunLoop狀態(tài)發(fā)生改變---%zd",activity);
});
//添加觀察者:監(jiān)聽(tīng)RunLoop的狀態(tài)
CFRunLoopAddObserver(CFRunLoopGetCurrent(),observer, kCFRunLoopDefaultMode);
//釋放Observer
CFRelease(observer);