淺談iOS中RunLoop的使用及原理

什么是RunLoop

從字面意思看

運行循環(huán)
Paste_Image.png

跑圈

基本作用
  • 保持程序的持續(xù)運行
  • 處理App中的各種事件(比如觸摸事件樟澜、定時器事件琐旁、Selector事件)
  • 節(jié)省CPU資源涮阔,提高程序性能:該做事時做事,該休息時休息
    ......
如果沒有RunLoop


int main(int argc, char * argv[]) {
    NSLog(@"execute main function");
    return 0;
}
  • 沒有RunLoop的情況下
  • 第3行后程序就結束了
如果有了RunLoop

int main(int argc, char * argv[]) {
    BOOL running = YES;
    do {
        // 執(zhí)行各種任務灰殴,處理各種事件
             // ......
    } while (running);
    return 0;
}
  • 有RunLoop的情況下
  • 由于main函數(shù)里面啟動了個RunLoop敬特,所以程序并不會馬上退出,保持持續(xù)運行狀態(tài)
main函數(shù)中的RunLoop
int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
  • UIApplicationMain函數(shù)內部就啟動了一個RunLoop
  • 所以UIApplicationMain函數(shù)一直沒有返回牺陶,保持了程序的持續(xù)運行
  • 這個默認啟動的RunLoop是跟主線程相關聯(lián)的

RunLoop對象

  • iOS中有2套API來訪問和使用RunLoop

  • Foundation

  • NSRunLoop

  • Core Foundation

  • CFRunLoopRef

  • NSRunLoop和CFRunLoopRef都代表著RunLoop對象

  • NSRunLoop是基于CFRunLoopRef的一層OC包裝伟阔,所以要了解RunLoop內部結構,需要多研究CFRunLoopRef層面的API(Core Foundation層面)

蘋果官方文檔

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

CFRunLoopRef是開源的

http://opensource.apple.com/source/CF/CF-1151.16/

RunLoop與線程
  • 每條線程都有唯一的一個與之對應的RunLoop對象

  • 主線程的RunLoop已經自動創(chuàng)建好了掰伸,子線程的RunLoop需要主動創(chuàng)建

  • RunLoop在第一次獲取時創(chuàng)建皱炉,在線程結束時銷毀

獲得RunLoop對象
Foundation

[NSRunLoop currentRunLoop]; // 獲得當前線程的RunLoop對象
[NSRunLoop mainRunLoop]; // 獲得主線程的RunLoop對象

Core Foundation

CFRunLoopGetCurrent(); // 獲得當前線程的RunLoop對象
CFRunLoopGetMain(); // 獲得主線程的RunLoop對象
RunLoop相關類
  • Core Foundation中關于RunLoop的5個類
  • CFRunLoopRef
  • CFRunLoopModeRef
  • CFRunLoopSourceRef
  • CFRunLoopTimerRef
  • CFRunLoopObserverRef
Paste_Image.png
CFRunLoopModeRef
  • CFRunLoopModeRef代表RunLoop的運行模式

  • 一個 RunLoop 包含若干個 Mode,每個Mode又包含若干個Source/Timer/Observer

  • 每次RunLoop啟動時狮鸭,只能指定其中一個 Mode合搅,這個Mode被稱作 CurrentMode

  • 如果需要切換Mode,只能退出Loop歧蕉,再重新指定一個Mode進入

  • 這樣做主要是為了分隔開不同組的Source/Timer/Observer灾部,讓其互不影響

CFRunLoopModeRef
  • 系統(tǒng)默認注冊了5個Mode:

  • kCFRunLoopDefaultMode:App的默認Mode,通常主線程是在這個Mode下運行

  • UITrackingRunLoopMode:界面跟蹤 Mode惯退,用于 ScrollView 追蹤觸摸滑動赌髓,保證界面滑動時不受其他 Mode 影響

  • UIInitializationRunLoopMode: 在剛啟動 App 時第進入的第一個 Mode,啟動完成后就不再使用

  • GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內部 Mode催跪,通常用不到

  • kCFRunLoopCommonModes: 這是一個占位用的Mode锁蠕,不是一種真正的Mode

CFRunLoopSourceRef
  • CFRunLoopSourceRef是事件源(輸入源)
    以前的分法
  • Port-Based Sources
  • Custom Input Sources
  • Cocoa Perform Selector Sources
    現(xiàn)在的分法
  • Source0:非基于Port的
  • Source1:基于Port的
CFRunLoopTimerRef
  • CFRunLoopTimerRef是基于時間的觸發(fā)器

  • 基本上說的就是NSTimer

CFRunLoopObserverRef
  • CFRunLoopObserverRef是觀察者,能夠監(jiān)聽RunLoop的狀態(tài)改變

  • 可以監(jiān)聽的時間點有以下幾個

Paste_Image.png

RunLoop處理邏輯-官方版

Paste_Image.png
Paste_Image.png

RunLoop處理邏輯-網友整理版

Paste_Image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末叠荠,一起剝皮案震驚了整個濱河市匿沛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌榛鼎,老刑警劉巖逃呼,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異者娱,居然都是意外死亡抡笼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門黄鳍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來推姻,“玉大人,你說我怎么就攤上這事框沟〔毓牛” “怎么了增炭?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拧晕。 經常有香客問我隙姿,道長,這世上最難降的妖魔是什么厂捞? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任输玷,我火速辦了婚禮,結果婚禮上靡馁,老公的妹妹穿的比我還像新娘欲鹏。我一直安慰自己,他們只是感情好臭墨,可當我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布赔嚎。 她就那樣靜靜地躺著,像睡著了一般裙犹。 火紅的嫁衣襯著肌膚如雪尽狠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天叶圃,我揣著相機與錄音袄膏,去河邊找鬼。 笑死掺冠,一個胖子當著我的面吹牛沉馆,可吹牛的內容都是我干的。 我是一名探鬼主播德崭,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼斥黑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了眉厨?” 一聲冷哼從身側響起锌奴,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎憾股,沒想到半個月后鹿蜀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡服球,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年茴恰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斩熊。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡往枣,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情分冈,我是刑警寧澤圾另,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站丈秩,受9級特大地震影響盯捌,放射性物質發(fā)生泄漏。R本人自食惡果不足惜蘑秽,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望箫攀。 院中可真熱鬧肠牲,春花似錦、人聲如沸靴跛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梢睛。三九已至肥印,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绝葡,已是汗流浹背深碱。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留藏畅,地道東北人敷硅。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像愉阎,于是被迫代替她去往敵國和親绞蹦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內容

  • 一榜旦、什么是runloop 字面意思是“消息循環(huán)幽七、運行循環(huán)”。它不是線程溅呢,但它和線程息息相關澡屡。一般來講,一個線程一次...
    WeiHing閱讀 8,152評論 11 111
  • Run loop 剖析:Runloop 接收的輸入事件來自兩種不同的源:輸入源(intput source)和定時...
    Mitchell閱讀 12,440評論 17 111
  • 如果沒有RunLoop main函數(shù)中的RunLoop 第14行代碼的UIApplicationMain函數(shù)內部就...
    JonesCxy閱讀 543評論 0 4
  • 1 RunLoop簡介 神秘的RunLoop藕届。一個應用開始運行以后放在那里挪蹭,如果不對它進行任何操作,這個應用就像靜...
    Claire_wu閱讀 1,773評論 3 30
  • 本文首發(fā)于我的個人博客:「程序員充電站」[https://itcharge.cn]文章鏈接:「傳送門」[https...
    ITCharge閱讀 60,375評論 50 540