OC底層基礎(chǔ):RunLoop

查看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

    1. Foundation : NSRunLoop
    2. Core Foundation : CFRunLoopRef
  • RunLoopCFRunloopRef都代表著RunLoop對象

    1. NSRunloop是基于CFRunLoopRef的一層OC包裝
    2. CFRunLoopRef是開源的
  • Foundation

    1. [NSRunLoop currentRunLoop]; 獲得當前線程的 RunLoop對象
    2. [NSRunLoop mainRunLoop]; 獲得主線程的RunLoop對象
  • Core Foundation

    1. CFRunLoopRefGetCurrent(); 獲得當前線程的 RunLoop對象
    2. CFRunLoopRefGetMain(); 獲得主線程的RunLoop對象

注:https://opensource.apple.com/tarballs/CF/

  • 程序并不會馬上退出刊愚,而是保持運行狀態(tài)
  • RunLoop的基本作用
    1. 保持程序的持續(xù)運行
    2. 處理App中各種事件(如:觸摸事件型将、定時器事件等)
    3. 節(jié)省CPU資源帆锋,提高程序性能:該做事時做事掉分,該休息時休息
    4. ……


      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個類
    1. CFRunLoopRef
    2. CFRunLoopModeRef
    3. CFRunLoopSourceRef
    4. CFRunLoopTimerRef
    5. 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

    1. CFRunLoopModeRef代表RunLoop的運行模式
    2. 一個RunLoop包含若干個Mode,每一個Mode又包含若干個sources0/sources1/Timer/observer
    3. RunLoop啟動時只能選擇其中一個Mode作為currentMode
    4. 如果需要切換Mode浊洞,只能退出當前Loop牵敷,再重新選擇一個Mode進入
      • 不同組的sources0/sources1/Timer/observer能分隔開來,互不影響
    5. 如果Mode里沒有sources0/sources1/Timer/observer法希,RunLoop會立馬退出
    6. 常見的兩種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
    1. 觸摸事件處理
    2. performSelector:onThread:
  • Source1
    1. 基于Port的線程間通信
    2. 系統(tǒng)事件捕捉
  • Timers
    1. NSTimer
    2. performSelector:withObject:afterDelay:
  • Observers
    1. 用于監(jiān)聽RunLoop的狀態(tài)
    2. UI刷新(BeforeWaiting
    3. Autorelease poolBeforeWaiting
RunLoop的運行邏輯.png

三、RunLoop休眠的實現(xiàn)原理

  • 等待消息
    1. 沒有消息就讓線程休眠
    2. 有消息就喚醒線程


      RunLoop休眠的實現(xiàn)原理.png

四屋剑、RunLoop在實際的應(yīng)用

  • 控制線程生命周期(線程贝迳活)
  • 解決NSTimer在滑動時停止工作的問題
  • 監(jiān)控應(yīng)用卡頓
  • 性能優(yōu)化

注:可能涉及的面試題

  • 講講RunLoop,項目中有用到嗎
  • RunLoop內(nèi)部實現(xiàn)邏輯
  • RunLoop和線程的關(guān)系
  • timerRunLoop的關(guān)系
  • 程序中添加每3秒響應(yīng)一次的NSTimer饼丘,當拖動tableViewtimer可能無法響應(yīng)要怎么解決
  • RunLoop是怎么響應(yīng)用戶操作的,具體流程是什么樣的
  • 說說RunLoop的幾種狀態(tài)
  • RunLoopmode作用是什么

上一篇:
OC底層基礎(chǔ):Block
下一篇:
OC底層基礎(chǔ):多線程GCD

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辽话,一起剝皮案震驚了整個濱河市肄鸽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌油啤,老刑警劉巖典徘,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異益咬,居然都是意外死亡逮诲,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梅鹦,“玉大人裆甩,你說我怎么就攤上這事∑胨簦” “怎么了嗤栓?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長箍邮。 經(jīng)常有香客問我茉帅,道長,這世上最難降的妖魔是什么锭弊? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任堪澎,我火速辦了婚禮,結(jié)果婚禮上味滞,老公的妹妹穿的比我還像新娘樱蛤。我一直安慰自己,他們只是感情好桃犬,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布刹悴。 她就那樣靜靜地躺著,像睡著了一般攒暇。 火紅的嫁衣襯著肌膚如雪土匀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天形用,我揣著相機與錄音就轧,去河邊找鬼。 笑死田度,一個胖子當著我的面吹牛妒御,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播镇饺,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼乎莉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奸笤?” 一聲冷哼從身側(cè)響起惋啃,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎监右,沒想到半個月后边灭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡健盒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年绒瘦,在試婚紗的時候發(fā)現(xiàn)自己被綠了称簿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡惰帽,死狀恐怖憨降,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情善茎,我是刑警寧澤券册,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站垂涯,受9級特大地震影響烁焙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耕赘,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一骄蝇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧操骡,春花似錦九火、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至是掰,卻和暖如春虑鼎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背键痛。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工炫彩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人絮短。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓江兢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親丁频。 傳聞我的和親對象是個殘疾皇子杉允,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容