初探Runloop

1.runloop是什么均蜜?

runloop 是一個(gè)運(yùn)行循環(huán)(死循環(huán));

return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 該句代碼默認(rèn)會(huì)開啟一個(gè)主線程

例證:


2.runloop有什么用抹竹? ? ?

? ? (1)保證線程不退出


? ? ? ?我們知道線程結(jié)束的條件是昌犹,線程中未有未執(zhí)行的任務(wù)

? ? ? ?所以為了保證主線程運(yùn)轉(zhuǎn)监婶,執(zhí)行 return UIApplicationMain(argc, argv, nil, ? ? ?NSStringFromClass([AppDelegate class])); 該句代碼創(chuàng)建了一個(gè)runloop

? ? ? 注意:(1)主線程:是指app啟動(dòng)時(shí)第一個(gè)創(chuàng)建的線程,在該線程中才能執(zhí)行UI有關(guān)操作宛蚓,除此之外其實(shí)和其它子線程沒有區(qū)分激捏,(這也是為什么UI作為屬性時(shí),使用的是nonatomic)

? ?(2)負(fù)責(zé)監(jiān)聽事件:觸摸事件凄吏、時(shí)鐘事件缩幸、網(wǎng)絡(luò)事件:


? ? ? ? 案例 ? 當(dāng)滑動(dòng)其他頁面時(shí)壹置,頂部輪播圖不會(huì)輪播

3.runloop和多線程

? (1) 線程默認(rèn)是不開啟runloop的,線程不被cpu收回的前提是線程中有未執(zhí)行完的任務(wù)


該線程開啟后表谊,不會(huì)執(zhí)行eat方法 因?yàn)?/p>

(1)钞护。線程已經(jīng)死掉了(oc對(duì)象保留,但線程已經(jīng)死掉了爆办,因?yàn)槲从形赐瓿傻娜蝿?wù)(runloop沒有開啟))


正確的方法是:







4.runloop 性能優(yōu)化(加載大圖時(shí)难咕,渲染圖片像素較高)

問題:當(dāng)用tableview顯示高清圖片時(shí)距辆,如果一屏的高清圖片過多余佃,導(dǎo)致在一個(gè)runloop中渲染圖片的時(shí)間過多,進(jìn)而不能及時(shí)響應(yīng)用戶的滑動(dòng)操作(在某個(gè)項(xiàng)目 *覓 中就出行過這種情況)導(dǎo)致滑動(dòng)時(shí)顯示出卡頓

注意:渲染圖片屬于runloop要做的事跨算,滑動(dòng)tableview也屬于runloop要處理的事情爆土,在一次性循環(huán)中,runloop既要渲染大量的高清圖片又要響應(yīng)拖拽事件诸蚕,因此就會(huì)顯得滑動(dòng)卡頓

解決思路:讓每個(gè)runloop中只渲染一張圖片步势,這樣就不會(huì)導(dǎo)致渲染很多圖片后,才響應(yīng)用戶的滑動(dòng)動(dòng)作

步驟

1.添加觀察runloop各個(gè)狀態(tài)的觀察者


2.把添加圖片的代碼加到一個(gè)數(shù)組中


3.添加一個(gè)間隔0.001秒的定時(shí)器背犯,保證線程每個(gè)0.001秒就被喚醒 然后執(zhí)行渲染圖片的任務(wù)坏瘩,因?yàn)闀r(shí)間間隔非常短,因此加載圖片非衬海快


4.定時(shí)器進(jìn)入休眠前執(zhí)行渲染某一張圖片的任務(wù)


注意點(diǎn):

(1)觀察runloop 要用到? CoreFoundation 框架中的 CFRunloop倔矾。 注意啦:CF是由C語言實(shí)現(xiàn)的,而不是Objective-C柱锹,所以如果用到了CF哪自,就需要手動(dòng)管理內(nèi)存,ARC是無能為力的禁熏;

CF中遇到create壤巷、new、copy 要記得手動(dòng)釋放內(nèi)存

例如:



(2)C語言中只能用函數(shù)指針來完成回調(diào)匹层,OC中當(dāng)然有很多方式:通知隙笆、block锌蓄、代理升筏、kvo


(3)橋接

先來說說「Core Foundation」(以下簡(jiǎn)稱CF)的歷史吧。當(dāng)年喬布斯被自己創(chuàng)辦的公司驅(qū)逐后瘸爽,成立了「NeXT Computer」,其實(shí)做的還是老本行:賣電腦您访,但依舊不景氣。好在NeXTSTEP系統(tǒng)表現(xiàn)還不錯(cuò)剪决,虧損不至于太嚴(yán)重灵汪。正好此時(shí)蘋果的市場(chǎng)份額大跌檀训,急需一個(gè)新的操作系統(tǒng),結(jié)果大家都知道了享言,喬布斯借此收購(gòu)峻凫,重新回到了蘋果。

這里就牽扯到了一個(gè)問題览露,如何讓舊有的系統(tǒng)(Mac OS 9)和NeXTSTEP合成為一個(gè)新系統(tǒng)荧琼?這就需要一個(gè)更為底層的核心庫(kù)可以供Mac Toolbox和OPENSTEP雙方調(diào)用。CF就這么誕生了差牛。

CF是由C語言實(shí)現(xiàn)的命锄,而不是Objective-C,所以如果用到了CF偏化,就需要手動(dòng)管理內(nèi)存脐恩,ARC是無能為力的。當(dāng)然因?yàn)镃F和Foundation之間的友好關(guān)系侦讨,它們之間的管理權(quán)也是可以移交的驶冒,這個(gè)后面再說。

Core Foundation框架(CoreFoundation.framework) 是一組C語言接口搭伤,它們?yōu)閕OS應(yīng)用程序提供基本數(shù)據(jù)管理和服務(wù)功能只怎。下面列舉該框架支持進(jìn)行管理的數(shù)據(jù)以及可提供的服務(wù):

群體數(shù)據(jù)類型 (數(shù)組、集合等)

程序包

字符串管理

日期和時(shí)間管理

原始數(shù)據(jù)塊管理

偏好管理

URL及數(shù)據(jù)流操作

線程和RunLoop

端口和soket通訊

Core Foundation框架和Foundation框架緊密相關(guān)怜俐,它們?yōu)橄嗤δ芴峁┙涌谏肀ぃ獸oundation框架提供Objective-C接口。如果您將Foundation對(duì)象和Core Foundation類型摻雜使用拍鲤,則可利用兩個(gè)框架之間的 “toll-free bridging”贴谎。所謂的Toll-free bridging是說您可以在某個(gè)框架的方法或函數(shù)同時(shí)使用Core Foundatio和Foundation 框架中的某些類型。很多數(shù)據(jù)類型支持這一特性季稳,其中包括群體和字符串?dāng)?shù)據(jù)類型擅这。每個(gè)框架的類和類型描述都會(huì)對(duì)某個(gè)對(duì)象是否為 toll-free bridged,應(yīng)和什么對(duì)象橋接進(jìn)行說明景鼠。


CoreFoundation 是C語言構(gòu)成 而Foundation 是用OC把CoreFoundation進(jìn)行包裝了一遍

CoreFoundation 和 Foundation 之間相互轉(zhuǎn)換就用到了橋接

橋接分為三種模式

第一種橋接方式? __bridge transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.(這種方式只是傳遞了指針仲翎,而沒有傳遞對(duì)象的所有權(quán),也就是如果str銷毀了铛漓,strC也不能用了)

CFStringRef strC = nil;

{

NSString *str = [NSString stringWithFormat:@"123"];

strC = (__bridge CFStringRef)(str);

}

NSLog(@"%@ ",strC);

第二種橋接方式? __bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.You are responsible for calling CFRelease or a related function to relinquish ownership of the object.(這種方式只是用于OC對(duì)象轉(zhuǎn)換為CF類型溯香,它會(huì)將對(duì)象的所有權(quán)轉(zhuǎn)移給strC,也就是說浓恶,即便str釋放了玫坛,strC也可以使用

注意 在ARC條件下,如果使用__bridge_retained橋接包晰,那么strC必須手動(dòng)釋放湿镀,因?yàn)闃蚪拥臅r(shí)候已經(jīng)將對(duì)象的所有轉(zhuǎn)移給了strC炕吸,而C語言的東西是不歸ARC管理的


NSString *str = [NSString stringWithFormat:@"123"];

CFStringRef strC = (__bridge_retained CFStringRef)str;

//CFStringRef StrC = CFBridgingRetain(str); 這一句和上面一句的效果一樣

NSLog(@"%@ %@",str,strC);

CFRelease(strC);


第三種橋接方式? __bridge_transfer or CFBridgingRelease moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.ARC is responsible for relinquishing ownership of the object.這種方式只是用于CF對(duì)象轉(zhuǎn)換為OC類型,它會(huì)將對(duì)象的所有權(quán)轉(zhuǎn)移給str勉痴,也就是說赫模,即便strC釋放了,str也可以使用

//注意 在ARC條件下蒸矛,如果使用__bridge_transfer橋接嘴瓤,那么strC不用手動(dòng)釋放,因?yàn)開_bridge_transfer會(huì)自動(dòng)釋放strC的

CFStringRef strC = CFStringCreateWithCString(nil, "456", kCFStringEncodingASCII);

NSString *str = (__bridge_transfer NSString*) (strC);

NSString *str = CFBridgingRelease(strC); //這一句和上面一句的效果一樣

NSLog(@"%@ %@",str,strC);

CFRelease(strC);

總結(jié)

runloop和線程之間的關(guān)系

* 每個(gè)線程有且僅有一個(gè)對(duì)應(yīng)的runloop莉钙,子線程的runloop默認(rèn)是沒有開啟的廓脆,但是主線程的runloop默認(rèn)是開啟的

*runloop是懶加載,獲得runloop等于開啟runloop 例如: ?[NSRunLoop currentRunLoop]

*runloop有5中mode(模式)磁玉,但是主要的是兩種模式:NSDefaultRunLoopMode(默認(rèn)模式)和UITrackingUIRunLoopMode(界面追蹤模式停忿,也就是頁面滑到時(shí)主線程會(huì)切換到UITrancking模式),要注意

**runloop啟動(dòng)時(shí)蚊伞,只能有一種模式席赂,要切換到另外一種模式,runloop要先退出再開啟时迫。

**每種模式都有source颅停、定時(shí)器、observe三種觸發(fā)模式掠拳,并且不同模式下癞揉,三種觸發(fā)是相互隔離的,也就是說溺欧,比如定時(shí)器1加到NSDefault這種模式下了喊熟,那么當(dāng)runloop啟動(dòng)時(shí)運(yùn)行在UITrancking模式下事,就不會(huì)接收到定時(shí)器1的觸發(fā)了

例如:NStimer定時(shí)滑動(dòng)的問題姐刁,如果NStimer只加入到NSDefault模式下芥牌,那么當(dāng)頁面滑動(dòng)時(shí),主線程的runloop從default模式退出聂使,開啟UITrancking模式壁拉,但是NStimer并沒有添加到UITrancking模式下,所以在滑動(dòng)頁面時(shí)柏靶,就收不到滑動(dòng)的觸發(fā)

參考

Core Foundation 框架 詳解

蘋果官方文檔Toll-Free Bridged Types

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弃理,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宿礁,更是在濱河造成了極大的恐慌案铺,老刑警劉巖蔬芥,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梆靖,死亡現(xiàn)場(chǎng)離奇詭異控汉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)返吻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門姑子,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人测僵,你說我怎么就攤上這事街佑。” “怎么了捍靠?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵沐旨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我榨婆,道長(zhǎng)磁携,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任良风,我火速辦了婚禮谊迄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烟央。我一直安慰自己统诺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布疑俭。 她就那樣靜靜地躺著粮呢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钞艇。 梳的紋絲不亂的頭發(fā)上鬼贱,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音香璃,去河邊找鬼这难。 笑死,一個(gè)胖子當(dāng)著我的面吹牛葡秒,可吹牛的內(nèi)容都是我干的姻乓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼眯牧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蹋岩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起学少,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤剪个,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后版确,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扣囊,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乎折,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侵歇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骂澄。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惕虑,靈堂內(nèi)的尸體忽然破棺而出坟冲,到底是詐尸還是另有隱情,我是刑警寧澤溃蔫,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布健提,位于F島的核電站,受9級(jí)特大地震影響伟叛,放射性物質(zhì)發(fā)生泄漏矩桂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一痪伦、第九天 我趴在偏房一處隱蔽的房頂上張望侄榴。 院中可真熱鬧,春花似錦网沾、人聲如沸癞蚕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桦山。三九已至,卻和暖如春醋旦,著一層夾襖步出監(jiān)牢的瞬間恒水,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工饲齐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钉凌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓捂人,卻偏偏與公主長(zhǎng)得像御雕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滥搭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345