iOS RunLoop總結(jié)

很多有關(guān)runloop的文章,都是長篇描述竹勉,看懵很多人飞盆,特別是C/C++代碼部分,看完下來次乓,發(fā)生了什么吓歇,我是誰,我在干什么票腰?runloop到底什么城看?
其實(shí),我們看runloop 很簡單杏慰,不為造輪子测柠,不為能鉆研出什么魔法出來

  • runloop 能干什么,項(xiàng)目中哪些場景用到了它
  • 面試的時(shí)候炼鞠,我怎么去回答,那么長篇大段的原理轰胁,我的天
    接下來谒主,跟著我的腳步,揭開runloop的面紗赃阀,先看看面試的時(shí)候需要的理論知識

1.runloop 是什么

  • runloop就是循環(huán)來處理程序運(yùn)行過程中出現(xiàn)的各種事件(比如說觸摸事件霎肯、UI刷新事件、定時(shí)器事件榛斯、Selector事件)观游,從而保持程序的持續(xù)運(yùn)行,而在沒有任何任務(wù)處理時(shí)驮俗,會讓線程休眠懂缕。

2.runloop與線程

  • 一條線程對應(yīng)一個(gè)RunLoop對象,每條線程都有唯一一個(gè)與之對應(yīng)的 RunLoop 對象

  • RunLoop保存在一個(gè)全局的Dictionary里王凑,線程作為key,RunLoop作為value搪柑。
    (key:線程 ,value:runloop)

  • RunLoop 對象在第一次獲取 RunLoop 時(shí)創(chuàng)建荤崇,銷毀則是在線程結(jié)束的時(shí)候拌屏。

  • 主線程的 RunLoop 對象系統(tǒng)自動(dòng)幫助我們創(chuàng)建好了潮针,而子線程的 RunLoop對象需要我們主動(dòng)創(chuàng)建和維護(hù)术荤。

這里主線程 runloop自動(dòng)創(chuàng)建,可能會被面試官深問是什么時(shí)候創(chuàng)建的每篷,怎么創(chuàng)建的瓣戚?看怎么回答

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

這是app程序,函數(shù)入口mian,在main里面焦读,直接return 了UIApplicationMain函數(shù)的返回值子库。一般rutern不是直接返回,這個(gè)就結(jié)束了嗎矗晃?為什么這里能一直保持程序不退出呢仑嗅?

其實(shí) UIApplicationMain 函數(shù)內(nèi)部幫我們開啟了主線程的 RunLoop, 內(nèi)部擁有一個(gè)無限循環(huán)的代碼(理解成do...while就OK)张症,這樣仓技,UIApplicationMain函數(shù)就不會立刻返回,只要程序不退出/崩潰俗他,它就一直循環(huán)脖捻。

3.runloop五種模式

  1. kCFRunLoopDefaultMode:App的默認(rèn)Mode,通常主線程是在這個(gè)Mode下運(yùn)行
  2. UITrackingRunLoopMode:界面跟蹤 Mode兆衅,用于 ScrollView 追蹤觸摸滑動(dòng)地沮,保證界面滑動(dòng)時(shí)不受其他 Mode 影響
  3. UIInitializationRunLoopMode: 在剛啟動(dòng) App 時(shí)第進(jìn)入的第一個(gè) Mode嗜浮,啟動(dòng)完成后就不再使用,會切換到kCFRunLoopDefaultMode
  4. GSEventReceiveRunLoopMode: 接受系統(tǒng)事件的內(nèi)部 Mode摩疑,通常用不到
  5. kCFRunLoopCommonModes: 這是一個(gè)占位用的Mode危融,作為標(biāo)記kCFRunLoopDefaultMode和UITrackingRunLoopMode用,并不是一種真正的Mode

現(xiàn)實(shí)中,需要用到runloop mode的時(shí)候雷袋,指定kCFRunLoopCommonModes就行了专挪,對于defaultMode與trackingMode來回切太麻煩,頭疼吧

面試被問到這個(gè)知識點(diǎn)片排,肯定會問 NSTimer

1)NSTimer 倒計(jì)時(shí)精確不準(zhǔn)寨腔。自測的話可以看打印log時(shí)間,只要是runloop的影響率寡,雖然我們把它的mode 設(shè)置成commondMode 還是會受影響迫卢;

2)NSTimer 循環(huán)引用的問題。怎么解決冶共,要么寫一個(gè)繼承NSObject類來實(shí)現(xiàn)乾蛤,要么用GCD來寫。具體相關(guān)代碼自己搜咯 [\斜眼笑]捅僵。

補(bǔ)充一下家卖,GCD并不是基于RunLoop的(除了dispatch 調(diào)度到main queue)

上面都是基本知識,接下里庙楚,還會問什么上荡,就是原理東西了,比如:runloop是怎么處理事件的馒闷?

觸摸事件:關(guān)鍵詞source1 souce0 酪捡,響應(yīng)鏈hit-Testing等等
那就看我發(fā)布的這篇文章
iOS 觸摸事件 hitTest touches nextResponder

環(huán)環(huán)相扣,面試就是那么難纳账,腦子里面沒有點(diǎn)墨水不行逛薇,哈哈,知道為什么你的隔壁同事為什么薪資比你高了吧疏虫,寫代碼可以不行永罚,但是能說,說的好卧秘,薪資高呢袱,我也羨慕他們,沒事斯议,跟我混产捞,我?guī)銈冏呱蠋p峰(吹水了哈,共同探討哼御,大家多指點(diǎn)坯临,一起進(jìn)步咯)

image

重點(diǎn)來了焊唬,Runloop 實(shí)際項(xiàng)目開發(fā)應(yīng)用場景用到了什么?
Runloop 應(yīng)用場景:
1)子線程 常駐存活
用于多次重復(fù)使用到的情景(網(wǎng)絡(luò)請求),如果存活看靠,就不用重復(fù)創(chuàng)建-銷毀
2)讓UITableView赶促、UICollectionView等延遲加載圖片
[imageView performSelector:@selector(setImage:) withObject:image afterDelay:0nModes:@[NSDefaultRunLoopMode]];
這算一個(gè)優(yōu)化點(diǎn),這里用的defaultMode挟炬,就是滾動(dòng)的時(shí)候不加載圖片鸥滨,停止?jié)L動(dòng)加載圖片
3)定時(shí)器-Timer (GCD來做定時(shí)器會更好)
4)阻止app崩潰
5)檢測app卡頓情況

有問題,請賜教谤祖,抱拳

ps:拓展

  • iOS應(yīng)用崩潰婿滓,常見的崩潰信息有EXC_BAD_ACCESS、SIGABRT XXXXXXX,而這里分為兩種情況粥喜,一種是未被捕獲的異常凸主,我們只需要添加一個(gè)回調(diào)函數(shù),并在應(yīng)用啟動(dòng)時(shí)調(diào)用一個(gè) API即可额湘;另一種是直接發(fā)送的 SIGABRT XXXXXXX,這里我們也需要監(jiān)聽各種信號卿吐,然后添加回調(diào)函數(shù)。
    針對情況一锋华,其實(shí)我們都見過嗡官。我們在收集App崩潰信息時(shí),需要添加一個(gè)函數(shù) NSSetUncaughtExceptionHandler(&HandleException)毯焕,參數(shù) 是一個(gè)回調(diào)函數(shù)衍腥,在回調(diào)函數(shù)里獲取到異常的原因,當(dāng)前的堆棧信息等保存到 dump文件芥丧,然后供下次打開App時(shí)上傳到服務(wù)器紧阔。
    其實(shí)坊罢,我們在HandleException回調(diào)函數(shù)中续担,可以獲取到當(dāng)前的RunLoop,然后獲取該RunLoop中的所有Mode活孩,手動(dòng)運(yùn)行一遍
    針對情況二物遇,首先針對多種要捕獲的信號,設(shè)置好回調(diào)函數(shù)憾儒,然后也是在回調(diào)函數(shù)中獲取RunLoop询兴,然后拿到所有的Mode,手動(dòng)運(yùn)行一遍起趾。
  • app卡頓情況監(jiān)測诗舰, 我們只需要在主線程的RunLoop中添加一個(gè)observer,檢測從 kCFRunLoopBeforeSources 到 kCFRunLoopBeforeWaiting 花費(fèi)的時(shí)間 是否過長训裆。如果花費(fèi)的時(shí)間大于某一個(gè)闕值眶根,我們就認(rèn)為有卡頓蜀铲,并把當(dāng)前的線程堆棧轉(zhuǎn)儲到文件中,并在以后某個(gè)合適的時(shí)間属百,將卡頓信息文件上傳到服務(wù)器记劝。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市族扰,隨后出現(xiàn)的幾起案子厌丑,更是在濱河造成了極大的恐慌,老刑警劉巖渔呵,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怒竿,死亡現(xiàn)場離奇詭異,居然都是意外死亡扩氢,警方通過查閱死者的電腦和手機(jī)愧口,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來类茂,“玉大人耍属,你說我怎么就攤上這事」欤” “怎么了厚骗?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兢哭。 經(jīng)常有香客問我领舰,道長,這世上最難降的妖魔是什么迟螺? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任冲秽,我火速辦了婚禮,結(jié)果婚禮上矩父,老公的妹妹穿的比我還像新娘锉桑。我一直安慰自己,他們只是感情好窍株,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布民轴。 她就那樣靜靜地躺著,像睡著了一般球订。 火紅的嫁衣襯著肌膚如雪后裸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天冒滩,我揣著相機(jī)與錄音微驶,去河邊找鬼。 笑死开睡,一個(gè)胖子當(dāng)著我的面吹牛因苹,可吹牛的內(nèi)容都是我干的较店。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼容燕,長吁一口氣:“原來是場噩夢啊……” “哼梁呈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蘸秘,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤官卡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后醋虏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寻咒,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年颈嚼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了毛秘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阻课,死狀恐怖叫挟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情限煞,我是刑警寧澤抹恳,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站署驻,受9級特大地震影響奋献,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜旺上,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一瓶蚂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宣吱,春花似錦窃这、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至倍奢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垒棋,已是汗流浹背卒煞。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叼架,地道東北人畔裕。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓衣撬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扮饶。 傳聞我的和親對象是個(gè)殘疾皇子具练,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348