開發中關於RunLoop和RunTime一些個人見解
RunLoop:
1. 實際上 RunLoop 就是一個函式,其內部是一個 do-while 迴圈。當你呼叫 CFRunLoopRun() 時,執行緒就會一直停留在這個迴圈裡;直到超時或被手動停止,該函式才會返回。
2. 作用:通過 RunLoop 機制實現省電,流暢,響應速度快,使用者體驗好,做效能優化和效能測試等
3. 特性:
a) iOS 中所有的事件監聽全部由執行迴圈負責
b) 主執行緒的 RunLoop 在應用啟動的時候就會自動建立
c) 其他執行緒則需要在該執行緒下自己啟動
d) 不能自己建立 RunLoop
e) RunLoop 並不是執行緒安全的,所以需要避免在其他執行緒上呼叫當前執行緒的 RunLoop
f) RunLoop 負責管理 autorelease pools
g) RunLoop 負責處理訊息事件,即輸入源事件、計時器事件和網路請求事情
4. 應用場景:
a) 建立常駐執行緒,執行一些會一直存在的任務。該執行緒的生命週期跟 App 相同
b) 維護執行緒的生命週期,讓執行緒不自動退出,isFinished 為 Yes 時退出
c) 在一定時間內監聽某種事件,或執行某種任務的執行緒
5. 蘋果使用RunLoop實現的功能:AutoreleasePool、事件響應、手勢識別、介面更新、定時器等
6. 蘋果不允許直接建立 RunLoop,它只提供了兩個自動獲取的函式:CFRunLoopGetMain() 和 CFRunLoopGetCurrent()。執行緒和 RunLoop 之間是一一對應的,其關係是儲存在一個全域性的 Dictionary 裡。執行緒剛建立時並沒有 RunLoop,如果你不主動獲取,那它一直都不會有。RunLoop 的建立是發生在第一次獲取時,RunLoop 的銷燬是發生線上程結束時。你只能在一個執行緒的內部獲取其 RunLoop(主執行緒除外)
7. Runloop實際應用
[[NSThread currentThread] setName:@"AFNetworking"];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
// 這裡主要是監聽某個 port,目的是讓這個runloop不會退出, Thread 不會回收
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
RunTime:
1. 簡介:執行時是一種面向物件的程式語言的執行環境,類似於 Java 的虛擬機器,OC 最主要的特點就是在程式執行時,以傳送訊息的方式呼叫方法,執行時是 OC 的核心,執行時系統庫API定義了一系列資料型別、函式和常量。執行時系統庫的公用API是使用C語言編寫的。
2. 執行時在開發中的主要應用場景:
a) 字典轉模型
i. 使用class_copyPropertyList獲取屬性陣列
ii. 遍歷字典得到屬性名字
iii. 使用KVC設定屬性的值;setValue:forKey:
b) 給分類增加關聯物件,開發框架時解耦,動態新增屬性
i. 使用執行時函式objc_getAssociatedObject(類,屬性名)獲取關聯的屬性
ii. 使用執行時函式objc_setAssociatedObject(類,屬性名,屬性例項,記憶體管理類別)動態新增關聯物件
c) 交換方法,在無法修改系統或者第三方框架的方法時,利用交換方法,先執行自己的方法,在執行系統或者第三方的框架的方法,這是黑魔法,對系統或者框架版本有很強的依賴性
i. 使用執行時函式class_getInstanceMethod(類,SEL)獲取例項方法
ii. 使用執行時函式method_exchangeImplementations(方法1,方法2)交換2個方法的實際入口
3. 第三方的運作場景
a) 在AFN的AFURLSessionManager.m檔案中,第363行就使用了交叉方法函式
b) 在AFN中,還使用了執行時函式class_addMethod新增方法
4. 常用的執行時方法: