此文僅為觀后筆記!?。〉刂罚?a target="_blank" rel="nofollow">http://v.youku.com/v_show/id_XODgxODkzODI0.html
Why Runloops ?
- 是程序一直運(yùn)行并接受用戶輸入;
- 決定程序在何時應(yīng)該處理哪些Event(事件);
- 調(diào)用解耦(Message Queue);
- 節(jié)省CPU時間
Runloops in Cocoa

Runloops in Cocoa
跟Runloop相關(guān)的東西
NSTimer、UIEvent、Autorelease、NSObject+NSDelayedPerforming、NSObject+NSThreadPerformAddition、CADisplayLink、CATransition、CAAnimation、dispatch_get_main_queue()、NSURLConnection
Runloop Callouts

6個調(diào)起函數(shù)
Runloop機(jī)制

runloop構(gòu)成元素簡圖
RunloopTimer的封裝
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
+ (CADisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)see;
- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;
.......
CFRunloopSource
- source是Runloop的數(shù)據(jù)源抽象類(protocol);
- Runloop定義了兩個Version的Source:
Source0:處理APP內(nèi)部事件、APP自己負(fù)責(zé)管理(觸發(fā)),如UIEvent、CFSocket;
Source1:由Runloop和內(nèi)核管理,mach port驅(qū)動,如:CFMachPort、CFMessagePort - 如有需要,可從中選擇一種來實現(xiàn)自己的Source;
- 當(dāng)然基本不會出現(xiàn)上一條。
CFRunloopObserver
向外部報告Runloop當(dāng)前狀態(tài)的更改,框架中很多機(jī)制都由RunloopObserver觸發(fā),比如:CAAnimation
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0),
kCFRunLoopBeforeTimers = (1UL << 1),
kCFRunLoopBeforeSources = (1UL << 2),
kCFRunLoopBeforeWaiting = (1UL << 5),
kCFRunLoopAfterWaiting = (1UL << 6),
kCFRunLoopExit = (1UL << 7),
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
RunloopObserver與Autorelease Pool
UIKit通過RunloopObserver在Runloop兩次Sleep減對AutoReleasePool進(jìn)行Pop和Push,將這次Loop中產(chǎn)生的Autorelease對象釋放。
CFRunLoopMode
- Runloop在同一時間只能且必須在一種特定Mode下跑;
- 更換Mode時,需要停止當(dāng)前Loop,然后重啟新Loop;
- Mode是iOS App滑動順暢的關(guān)鍵;
- 可以自定義Mode(基本用不到)。
NSDefaultRunloopMode:默認(rèn)狀態(tài),空閑狀態(tài)。
UITrackingRunLoopMode:滑動ScrollView時,若想保證Timer不被ScrollView影響,則需添加到NSRunLoopCommonModes。
UIInitializationRunLoopMode:私有,App啟動時。
NSRunLoopCommonModes:Mode集合
RunLoop與dispatch_get_main_queue()
GCD中dispatch到main queue的block被分發(fā)到main RunLoop執(zhí)行。
RunLoop的掛起與喚醒
- 指定用于喚醒的mach_port端口
- 調(diào)用mach_msg監(jiān)聽喚醒端口,被喚醒前,系統(tǒng)內(nèi)核將這個線程掛起,停留在mach_msg_trap狀態(tài);
-
有另一個線程(或另一個進(jìn)程中的某個線程)向內(nèi)核發(fā)送這個端口的msg后,trap狀態(tài)唄喚醒,RunLoop繼續(xù)開始干活。
偽代碼
RunLoop實踐
AFNetworking中RunLoop的創(chuàng)建

AFNetworking中RunLoop的創(chuàng)建
UITableView延遲加載圖片的新思路

UITableView延遲加載圖片
讓Crash的App回光返照

接到Crash的Singal后手動重啟RunLoop
Async Test Case

RunLoop sleep前驗證
RunLoop源碼
地址:https://opensource.apple.com/source/CF/CF-855.17/CFRunLoop.c.auto.html
