6.運(yùn)行時(shí)


1.運(yùn)行時(shí)簡介

就是在程序運(yùn)行時(shí)候的一些機(jī)制,其中主要是消息機(jī)制,oc在調(diào)用方法的時(shí)候,其實(shí)就是發(fā)送消息;而且oc在編譯階段,是不確定要調(diào)用哪個(gè)函數(shù)的,只有在運(yùn)行的時(shí)候才會(huì)找對(duì)應(yīng)的函數(shù)來調(diào)用

2.消息發(fā)送機(jī)制

2.1方法調(diào)用的本質(zhì)就是利用runtime發(fā)送消息

獲取類對(duì)象,然后去發(fā)送注冊(cè)方法的消息,去調(diào)用,這只是調(diào)用沒有參數(shù)的

objc_msgSend(objc_getClass("NSObject"),sel_registerName("alloc"))

消息機(jī)制的用處:1.可以裝逼。2.可以用runTime調(diào)用類的私有方法

面試時(shí)候會(huì)問:方法是怎么調(diào)用的?

這時(shí)候要知道不同的方法,它存到了什么地方,對(duì)象方法存到對(duì)應(yīng)的類里面,類方法存到了元類里面【meta class】(其實(shí)類也是對(duì)象,它是元類的實(shí)例對(duì)象),而元類是根元類的對(duì)象 root meta class

? ? ? ?1.所以首先要明確去哪個(gè)類查找方法,這時(shí)候就要通過isa指針,它指向的就是你方法所在的類中(每個(gè)類都有一個(gè)方法列表,methordList,在調(diào)用發(fā)方法的時(shí)候,底層是用消息機(jī)制來實(shí)現(xiàn)的,這時(shí)候它會(huì)把方法編號(hào)給你傳過來,可以根據(jù)方法編號(hào),在方法列表中查出所要調(diào)用的方法,在查找的時(shí)候它也是有算法的,因?yàn)橐粋€(gè)類中可能有很多方法,如果一個(gè)一個(gè)遍歷會(huì)很耗時(shí)間,這個(gè)算法是一個(gè)哈希算法,具體怎么算的就不清楚了,反正就是加快了查找的速度)

? ? ? 2.在找到方法之后,其實(shí)只是找到了一個(gè)方對(duì)應(yīng)的函數(shù)名,這時(shí)候要根據(jù)這個(gè)函數(shù)名去找對(duì)應(yīng)的函數(shù)實(shí)現(xiàn)(函數(shù)名其實(shí)就相當(dāng)于函數(shù)的一個(gè)入口)-------(在內(nèi)存中我們是有一塊區(qū)域的:方法區(qū)? 就是通過方法名在這個(gè)區(qū)域找到方法實(shí)現(xiàn)的)

3.交換方法(如果想要在用運(yùn)行時(shí)時(shí)候有提示:在Build Setting中搜索msg,設(shè)置成NO)

這個(gè)的應(yīng)用場景:當(dāng)自定義的一個(gè)類的方法很難維護(hù),并且這個(gè)方法用的還很頻繁,而你目前又想重構(gòu),但卻不想影響當(dāng)前功能,或者是想在系統(tǒng)的一些方法中填一些新的功能,可以使用運(yùn)行時(shí)交換方法,一句話,就是交換兩個(gè)方法的實(shí)現(xiàn):注意如果是要在原方法中添加新的參數(shù)的話,那么是不能使用交換方法的,因?yàn)闆]什么意義,(但是減少參數(shù)是可以的,因?yàn)樗粨Q時(shí)候,參數(shù)也是一一對(duì)應(yīng)進(jìn)行交換的)

1.創(chuàng)建這個(gè)類的分類:如果是系統(tǒng)方法,那么創(chuàng)建分類,如果是自定義的類,那么就直接在類里面重寫load方法,

2.在分類中重寫load方法,load方法是在這個(gè)類第一次調(diào)用的時(shí)候調(diào)用一次,下一次無論是子類還是本類再次調(diào)用都不會(huì)調(diào)用了,initialize這個(gè)類方是:當(dāng)?shù)谝淮渭虞d這個(gè)類的時(shí)候會(huì)調(diào)用一次,但是當(dāng)子類加載時(shí)候還會(huì)調(diào)用一次;

3.交換兩個(gè)方法

4.動(dòng)態(tài)添加方法(動(dòng)態(tài)添加方法首先不需要聲明)

會(huì)問到performSelector這個(gè)方法用沒用過

5.萬能跳轉(zhuǎn):在NSObject的分類中,寫一個(gè)方法,方法需要穿入一個(gè)字典,字典中包括所跳頁面的類名,和所要發(fā)的參數(shù),同時(shí)參數(shù)的名稱要和頁面所接收的參數(shù)屬性名稱一樣,然后運(yùn)用運(yùn)行時(shí),便利屬性名,然后給相同的屬性賦值,用kvc,然后獲得跟控制器,然后跳轉(zhuǎn),具體實(shí)現(xiàn)過程如下圖,這個(gè)可以解耦合


6.動(dòng)態(tài)添加屬性:其實(shí)就是給一個(gè)對(duì)象添加一個(gè)關(guān)聯(lián)

應(yīng)用場景:

1.一般是想給系統(tǒng)的類添加屬性方便開發(fā),一般會(huì)在系統(tǒng)類的分類中,申明get和set方法,然后調(diào)用objc_setAssociate添加關(guān)聯(lián),調(diào)用objc_getAssociate獲取關(guān)聯(lián),這樣就可以動(dòng)態(tài)的將值賦值給這個(gè)關(guān)聯(lián)

2.當(dāng)自己封裝了一個(gè)類,已經(jīng)打包SDK,同時(shí)又不想動(dòng)它,但現(xiàn)在又得添加新的屬性,那么就可以在類的分類中動(dòng)態(tài)添加屬性了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,082評(píng)論 0 9
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,900評(píng)論 33 466
  • 參數(shù)自一個(gè)指針,指向類的要接收消息的實(shí)例。 OP在處理該信息的方法的選擇。 ......可變參數(shù)列表包含參數(shù)的方法...
    reallychao閱讀 897評(píng)論 0 0
  • 原文出處:南峰子的技術(shù)博客 Objective-C語言是一門動(dòng)態(tài)語言,它將很多靜態(tài)語言在編譯和鏈接時(shí)期做的事放到了...
    _燴面_閱讀 1,439評(píng)論 1 5
  • Objective-C語言是一門動(dòng)態(tài)語言,他將很多靜態(tài)語言在編譯和鏈接時(shí)期做的事情放到了運(yùn)行時(shí)來處理。這種動(dòng)態(tài)語言...
    tigger丨閱讀 1,602評(píng)論 0 8

友情鏈接更多精彩內(nèi)容