查看oc文件底層結(jié)構(gòu)
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc xxx.m
支持ARC、指定運行時系統(tǒng)版本
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-15.0.0 xxx.m
一爱只、RunLoop基礎(chǔ)
1. RunLoop對象
-
iOS
中有兩套API
來訪問和使用RunLoop
-
Foundation
:NSRunLoop
-
Core Foundation
:CFRunLoopRef
-
-
RunLoop
和CFRunloopRef
都代表著RunLoop
對象-
NSRunloop
是基于CFRunLoopRef
的一層OC包裝 -
CFRunLoopRef
是開源的
-
-
Foundation
-
[NSRunLoop currentRunLoop];
獲得當前線程的RunLoop
對象 -
[NSRunLoop mainRunLoop];
獲得主線程的RunLoop
對象
-
-
Core Foundation
-
CFRunLoopRefGetCurrent();
獲得當前線程的RunLoop
對象 -
CFRunLoopRefGetMain();
獲得主線程的RunLoop
對象
-
注:https://opensource.apple.com/tarballs/CF/
- 程序并不會馬上退出刊愚,而是保持運行狀態(tài)
-
RunLoop
的基本作用- 保持程序的持續(xù)運行
- 處理App中各種事件(如:觸摸事件型将、定時器事件等)
- 節(jié)省CPU資源帆锋,提高程序性能:該做事時做事掉分,該休息時休息
-
……
RunLoop的基本作用1.png
RunLoop的基本作用2.png
2 . RunLoop與線程
- 每條線程都有唯一的一個與之對應(yīng)的
RunLoop
對象 -
RunLoop
保存在一個全局的Dictionary
里僧免,線程作為key
刑赶,RunLoop
作為value
- 線程剛創(chuàng)建時并沒有
RunLoop
對象,RunLoop
會在第一次獲取它時創(chuàng)建 -
RunLoop
會在線程結(jié)束時銷毀 - 主線程的
RunLoop
已經(jīng)自動獲榷谩(創(chuàng)建)撞叨,子線程默認沒有開啟RunLoop
3. RunLoop相關(guān)的類
- Core Foundation中關(guān)于RunLoop的5個類
CFRunLoopRef
CFRunLoopModeRef
CFRunLoopSourceRef
CFRunLoopTimerRef
CFRunLoopObserverRef
typedef struct __CFRunLoop * CFRunLoopRef;
struct __CFRunLoop {
pthread_t _pthread;
CFMutableSetRef _commonModes;
CFMutableSetRef _commonModeItems;
CFRunLoopModeRef _currentMode;
CFMutableSetRef _modes;
};
typedef struct __CFRunLoopMode *CFRunLoopModeRef;
struct __CFRunLoopMode {
CFStringRef _name;
CFMutableSetRef _sources0;
CFMutableSetRef _sources1;
CFMutableArrayRef _observers;
CFMutableArrayRef _timers;
};
RunLoop相關(guān)的類.png
-
CFRunLoopModeRef
-
CFRunLoopModeRef
代表RunLoop
的運行模式 - 一個
RunLoop
包含若干個Mode
,每一個Mode
又包含若干個sources0
/sources1
/Timer
/observer
-
RunLoop
啟動時只能選擇其中一個Mode
作為currentMode
- 如果需要切換
Mode
浊洞,只能退出當前Loop
牵敷,再重新選擇一個Mode
進入- 不同組的
sources0
/sources1
/Timer
/observer
能分隔開來,互不影響
- 不同組的
- 如果
Mode
里沒有sources0
/sources1
/Timer
/observer
法希,RunLoop
會立馬退出 - 常見的兩種Mode
-
kCFRunLoopDefaultMode
(NSDefaultRunLoopMode
):App的默認Mode枷餐,通常主線程是在這個Mode下運行 -
UITrackingRunLoopMode
:界面跟蹤Mode
,用于ScrollView
追蹤觸摸滑動苫亦,保證界面滑動時不受其他Mode
影響
-
-
CFRunLoopObserverRef
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), //即將進入Loop
kCFRunLoopBeforeTimers = (1UL << 1), // 即將處理Timer
kCFRunLoopBeforeSources = (1UL << 2), // 即將處理Source
kCFRunLoopBeforeWaiting = (1UL << 5), // 即將進入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 剛從休眠中喚醒
kCFRunLoopExit = (1UL << 7), // 即將退出Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
二毛肋、RunLoop的運行邏輯
- Source0
- 觸摸事件處理
performSelector:onThread:
- Source1
- 基于Port的線程間通信
- 系統(tǒng)事件捕捉
- Timers
- NSTimer
performSelector:withObject:afterDelay:
- Observers
- 用于監(jiān)聽
RunLoop
的狀態(tài) - UI刷新(
BeforeWaiting
) -
Autorelease pool
(BeforeWaiting
)
- 用于監(jiān)聽
RunLoop的運行邏輯.png
三、RunLoop休眠的實現(xiàn)原理
- 等待消息
- 沒有消息就讓線程休眠
-
有消息就喚醒線程
RunLoop休眠的實現(xiàn)原理.png
四屋剑、RunLoop在實際的應(yīng)用
- 控制線程生命周期(線程贝迳活)
- 解決
NSTimer
在滑動時停止工作的問題 - 監(jiān)控應(yīng)用卡頓
- 性能優(yōu)化
注:可能涉及的面試題
- 講講
RunLoop
,項目中有用到嗎 -
RunLoop
內(nèi)部實現(xiàn)邏輯 -
RunLoop
和線程的關(guān)系 -
timer
與RunLoop
的關(guān)系 - 程序中添加每3秒響應(yīng)一次的
NSTimer
饼丘,當拖動tableView
時timer
可能無法響應(yīng)要怎么解決 -
RunLoop
是怎么響應(yīng)用戶操作的,具體流程是什么樣的 - 說說
RunLoop
的幾種狀態(tài) -
RunLoop
的mode
作用是什么
上一篇:
OC底層基礎(chǔ):Block
下一篇:
OC底層基礎(chǔ):多線程GCD