實(shí)際上RunLoop 就是一個(gè)函數(shù)杖狼,其內(nèi)部是一個(gè)do-while 循環(huán)充石。當(dāng)你調(diào)用CFRunLoopRun() 時(shí)榛臼,線程就會(huì)一直停留在這個(gè)循環(huán)里;直到超時(shí)或被手動(dòng)停止恩静,該函數(shù)才會(huì)返回焕毫。
作用:通過(guò)RunLoop 機(jī)制實(shí)現(xiàn)省電,流暢驶乾,響應(yīng)速度快邑飒,用戶體驗(yàn)好,做性能優(yōu)化和性能測(cè)試等
特性:
a) iOS 中所有的事件監(jiān)聽(tīng)全部由運(yùn)行循環(huán)負(fù)責(zé)
b) 主線程的RunLoop 在應(yīng)用啟動(dòng)的時(shí)候就會(huì)自動(dòng)創(chuàng)建
c) 其他線程則需要在該線程下自己?jiǎn)?dòng)
d) 不能自己創(chuàng)建RunLoop
e) RunLoop 并不是線程安全的级乐,所以需要避免在其他線程上調(diào)用當(dāng)前線程的RunLoop
f) RunLoop 負(fù)責(zé)管理 autorelease pools
g) RunLoop 負(fù)責(zé)處理消息事件疙咸,即輸入源事件、計(jì)時(shí)器事件和網(wǎng)絡(luò)請(qǐng)求事情
應(yīng)用場(chǎng)景:
a) 創(chuàng)建常駐線程风科,執(zhí)行一些會(huì)一直存在的任務(wù)撒轮。該線程的生命周期跟App 相同
b) 維護(hù)線程的生命周期,讓線程不自動(dòng)退出贼穆,isFinished 為Yes 時(shí)退出
c) 在一定時(shí)間內(nèi)監(jiān)聽(tīng)某種事件题山,或執(zhí)行某種任務(wù)的線程
蘋果使用RunLoop實(shí)現(xiàn)的功能:AutoreleasePool、事件響應(yīng)故痊、手勢(shì)識(shí)別顶瞳、界面更新、定時(shí)器等
蘋果不允許直接創(chuàng)建RunLoop,它只提供了兩個(gè)自動(dòng)獲取的函數(shù):CFRunLoopGetMain() 和CFRunLoopGetCurrent()慨菱。線程和RunLoop 之間是一一對(duì)應(yīng)的焰络,其關(guān)系是保存在一個(gè)全局的Dictionary 里。線程剛創(chuàng)建時(shí)并沒(méi)有RunLoop抡柿,如果你不主動(dòng)獲取,那它一直都不會(huì)有等恐。RunLoop 的創(chuàng)建是發(fā)生在第一次獲取時(shí)洲劣,RunLoop 的銷毀是發(fā)生在線程結(jié)束時(shí)。你只能在一個(gè)線程的內(nèi)部獲取其RunLoop(主線程除外)
Runloop實(shí)際應(yīng)用 [[NSThread currentThread] setName:@"AFNetworking"]; NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; // 這里主要是監(jiān)聽(tīng)某個(gè)port课蔬,目的是讓這個(gè)runloop不會(huì)退出囱稽,Thread 不會(huì)回收 [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; [runLoop run];
RunTime
簡(jiǎn)介:運(yùn)行時(shí)是一種面向?qū)ο蟮木幊陶Z(yǔ)言的運(yùn)行環(huán)境,類似于java 的虛擬機(jī)二跋,OC 最主要的特點(diǎn)就是在程序運(yùn)行時(shí)战惊,以發(fā)送消息的方式調(diào)用方法,運(yùn)行時(shí)是OC 的核心扎即,運(yùn)行時(shí)系統(tǒng)庫(kù)API定義了一系列數(shù)據(jù)類型吞获、函數(shù)和常量。運(yùn)行時(shí)系統(tǒng)庫(kù)的公用API是使用C語(yǔ)言編寫的谚鄙。
運(yùn)行時(shí)在開(kāi)發(fā)中的主要應(yīng)用場(chǎng)景:
a) 字典轉(zhuǎn)模型
i. 使用class_copyPropertyList獲取屬性數(shù)組
ii. 遍歷字典得到屬性名字
iii. 使用KVC設(shè)置屬性的值各拷;setValue:forKey:
b) 給分類增加關(guān)聯(lián)對(duì)象,開(kāi)發(fā)框架時(shí)解耦闷营,動(dòng)態(tài)添加屬性
i. 使用運(yùn)行時(shí)函數(shù)objc_getAssociatedObject(類烤黍,屬性名)獲取關(guān)聯(lián)的屬性
ii. 使用運(yùn)行時(shí)函數(shù)objc_setAssociatedObject(類,屬性名傻盟,屬性實(shí)例速蕊,內(nèi)存管理類別)動(dòng)態(tài)添加關(guān)聯(lián)對(duì)象
c) 交換方法,在無(wú)法修改系統(tǒng)或者第三方框架的方法時(shí)娘赴,利用交換方法规哲,先執(zhí)行自己的方法,在執(zhí)行系統(tǒng)或者第三方的框架的方法诽表,這是黑魔法媳叨,對(duì)系統(tǒng)或者框架版本有很強(qiáng)的依賴性
i. 使用運(yùn)行時(shí)函數(shù)class_getInstanceMethod(類,SEL)獲取實(shí)例方法
ii. 使用運(yùn)行時(shí)函數(shù)method_exchangeImplementations(方法1关顷,方法2)交換2個(gè)方法的實(shí)際入口
第三方的運(yùn)作場(chǎng)景
a) 在AFN的AFURLSessionManager.m文件中糊秆,第363行就使用了交叉方法函數(shù)
b) 在AFN中,還使用了運(yùn)行時(shí)函數(shù)class_addMethod添加方法
常用的運(yùn)行時(shí)方法: