從接觸iOS到如今也有將近兩年了,對iOS中的RunLoop也有了必定的認識,下面講講我的對RunLoop的理解。html
初識RunLoop程序員
RunLoops是與線程相關聯的基礎部分,一個Run Loop就是事件處理循環,他是用來調度和協調接收到的事件處理。使用RunLoop的目的,就是使的線程有工做須要作的時候忙碌起來,當沒事作的時候,又可使得線程休眠。swift
咱們通常程序就是執行一個線程,是一條直線.有起點終點.而runloop就是一直在線程上面畫圓圈,一直在跑圈,除非切斷不然一直在運行。網上說的比喻很好,直線就像曇花一現同樣,圓就像OS,一直運行直到你關機爲止。網絡
RunLoop資料app
蘋果官方文檔:框架
CFRunLoopRef是開源的:動畫
http://opensource.apple.com/source/CF/CF-1151.16/spa
iOS中有兩套API來訪問和使用RunLoop線程
NSRunLoop和CFRunLoopRef都表明着RunLoop對象
NSRunLoop是基於CFRunLoopRef的一層OC包裝, 因此要了解RunLoop內部結構, 須要多研究CFRunLoopRef層面的API(Core Foundation層面)
[NSRunLoop currentRunLoop]; // 得到當前線程的RunLoop對象 [NSRunLoop mainRunLoop]; // 得到主線程的RunLoop對象
CFRunLoopGetCurrent(); // 得到當前線程的RunLoop對象 CFRunLoopGetMain(); // 得到主線程的RunLoop對象
若是在主線程中: 當前線程的RunLoop對象和主線程的RunLoop對象取得的是相同的。
CFRunLoopSourceRef
RunLoop
包含若干個Mode
,每一個Mode
又包含若干個Source
/Timer
/Observer
[NSRunLoop currentRunLoop].currentMode
)Source
/Timer
/Observer
,讓其互不影響(切換模式是爲了,讓它按照另外一個模式的Source,Timer,Observer來跑圈, 互不影響)RunLoop 啓動必需要傳入一個模式,RunLoop有多個模式, 可是每次只能運行一種模式
RunLoop定義兩個Version的Source
向內部報告RunLoop當前狀態的更改 CAAnimation
能夠監聽的時間點以下幾點:
UIKit經過RunLoopObserver在RunLoop兩次Sleep間對AutoreleasePool進行pop和push,將此次Loop中產生的Autorelease對象釋放。(好像swift中沒有關於釋放的問題)
CFRunLoopModeRef
RunLoop在同一時段只能且必須在一種特定Mode下Run 更換Mode時, 須要暫停當前的Loop,而後重啓新的Loop NSDefalutRunLoopMode 默認狀態.空閒狀態 UITrackingRunLoopMode 滑動ScrollView UIInitializationRunLoopMode 私有,App啓動時 NSRunLoopCommonModes 默認包括上面第一和第二
/** * 這個方法內部實現是: 建立timer,添加到RunLoop中的默認的Mode中,RunLoop啓動這個mode,取出這個mode中timer來用 */ [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(run) userInfo:nil repeats:YES]; /** * 上面的代碼等同於下面的 */ // 建立Timer NSTimer *timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(run) userInfo:nil repeats:YES]; // 定時器只運行在 NSDefaultRunLoopMode 模式下, 一旦RunLoop進入其餘模式,這個定時器就不會工做 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; // 若是拖動時, 咱們將定時器添打上這個NSRunLoopCommonModes的標記 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; NSLog(@"-----------%@", [NSRunLoop currentRunLoop]); /** * 定時器會跑在標記爲common modes的模式下(這個模式只是個標記) * RunLoop會尋找帶有common標籤的模式,有這個標籤的,均可以跑 * 打印當前的RunLoop信息輸出爲:(有common modes標籤的有兩個,UITrackingRunLoopMode和kCFRunLoopDefaultMode),因此定時器能夠在這兩個模式下跑, RunLoop只會運行一種模式 common modes = <CFBasicHash 0x7fb8b2700490 [0x10ec6ba40]>{type = mutable set, count = 2, entries => 0 : <CFString 0x10fba2210 [0x10ec6ba40]>{contents = "UITrackingRunLoopMode"} 2 : <CFString 0x10ec8c5e0 [0x10ec6ba40]>{contents = "kCFRunLoopDefaultMode"} } */
AFNetWorking 中建立RunLoop
[[NSThread currentThread] setName:@"AFNetworking"]; NSRunLoop *runloop = [NSRunLoop currentRunLoop]; [runLoop addPort:[NSMachPort port] forMode:NSDefalutRunLoopMode]//一直活着 [runLoop run];
這在處理網絡響應是一個很好的方法
UITrackingRunLoopMode 與 NSTimer
// 默認狀況下NSTimer被加入NSDefalutRunLoopMode //若是想NSTimer受到組件或者動畫影響 添加到NSRunLoopCommonModes [[NSRunLoop currentRunLoop]addTimer:timer...forMode:NSRunLoopCommonModes];
RunLoop的處理邏輯是什麼呢?
每次運行run loop,你線程的run loop對會自動處理以前未處理的消息,並通知相關的觀察者。具體的順序以下:
好的文章都是值得反覆看的,咱們在不一樣的階段來相同的文章或資料都能有不一樣的收穫, 提升本身對知識的理解,聲明一下:最好是本身理解後再總結一次,不要一味的收藏, 每一個程序員都有着成爲大牛的潛質,只在是否努力。加油 技術宅們!