Runloop學(xué)習(xí)筆記

此文僅為觀后筆記!?。〉刂罚?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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容