你要理解的Runtime知識(shí)點(diǎn)

博客地址:張飛的技術(shù)博客
在學(xué)習(xí)Runtime的過(guò)程中,有不少的知識(shí)點(diǎn)是平時(shí)難以接觸到的咕娄。所以剛開(kāi)始接觸Runtime的時(shí)候會(huì)碰到好些不熟悉的小知識(shí)點(diǎn)昌执。下面就隨我扒一扒Runtime中那些需要知道的小知識(shí)點(diǎn)吧摄杂!

SEL

SEL是一種類型精置,該類型表示對(duì)方法的一種封裝计寇,平時(shí)我們說(shuō)的選擇器selector就是它啦!Objective-C在編譯時(shí)候呢脂倦,會(huì)依據(jù)每一個(gè)方法的名字、參數(shù)序列元莫,生成一個(gè)唯一的整型標(biāo)識(shí)(Int類型的地址)赖阻,這個(gè)標(biāo)識(shí)就是SEL。也就是說(shuō)每一個(gè)SEL對(duì)應(yīng)一個(gè)方法踱蠢,根據(jù)一個(gè)SEL就能找到一個(gè)方法火欧,然后對(duì)它進(jìn)行調(diào)用等操作。其實(shí)我們也可以理解為SEL是一個(gè)方法的指針(實(shí)際上不是)茎截。來(lái)看看它的真面目吧,在objc.h的49行處可以發(fā)現(xiàn):

/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;

這樣看來(lái)SEL的本質(zhì)是一個(gè)objc_selector類型的結(jié)構(gòu)體指針苇侵。那該如何生成一個(gè)SEL類型的數(shù)據(jù)呢?編譯器提供的有選擇器@selector,NSSelectorFromString()方法企锌,sel_registerName函數(shù)榆浓。

SEL methodSel1 = @selector(method);
SEL methodSel2 = NSSelectorFromString(method);
```
>NOTE:只要方法名一樣,那么這個(gè)方法的SEL就一樣撕攒,不管同名的方法是有沒(méi)有關(guān)系(繼承),即使在不同的類方法名一樣那么這個(gè)方法的SEL也是一樣的陡鹃。但是同一個(gè)類中不能存在同名方法(即使參數(shù)類型一樣也不行,當(dāng)然參數(shù)個(gè)數(shù)不一樣可以)抖坪,在不同的類里面是可以有同名方法的萍鲸,不同類的實(shí)例對(duì)象執(zhí)行相同的selector時(shí),會(huì)在各自的方法列表中去根據(jù)selector去尋找自己對(duì)應(yīng)的IMP擦俐。

本質(zhì)上脊阴,SEL只是一個(gè)指向方法的指針(準(zhǔn)確的說(shuō),只是一個(gè)根據(jù)方法名hash化了的KEY值蚯瞧,能唯一代表一個(gè)方法)嘿期,它的存在只是為了加快方法的查詢速度。

###IMP
上面講了状知,根據(jù)SEL能尋找到函數(shù)秽五,其實(shí)IMP才是真正指向函數(shù)的指針,它指向了函數(shù)實(shí)現(xiàn)的首地址饥悴。其實(shí)SEL就是為了查找方法的IMP的坦喘。取得IMP后盲再,我們就獲得了執(zhí)行這個(gè)方法代碼的入口點(diǎn),此時(shí)瓣铣,我們就可以像調(diào)用普通的C語(yǔ)言函數(shù)一樣來(lái)使用這個(gè)函數(shù)指針了答朋。

>NOTE:通過(guò)取得IMP,我們可以跳過(guò)Runtime的消息傳遞機(jī)制棠笑,直接執(zhí)行IMP指向的函數(shù)實(shí)現(xiàn)梦碗,這樣省去了Runtime消息傳遞過(guò)程中所做的一系列查找操作,會(huì)比直接向?qū)ο蟀l(fā)送消息高效一些蓖救。

###Method
Method是一個(gè)結(jié)構(gòu)體洪规,用于表示類中定義的方法。實(shí)際上相當(dāng)于在SEL和IMP之間作了一個(gè)映射循捺。有了SEL斩例,我們便可以找到對(duì)應(yīng)的IMP,從而調(diào)用方法的實(shí)現(xiàn)代碼从橘。
>方法操作相關(guān)函數(shù):

``` Objective-C
// 調(diào)用指定方法的實(shí)現(xiàn)
id method_invoke ( id receiver, Method m, ... );
// 調(diào)用返回一個(gè)數(shù)據(jù)結(jié)構(gòu)的方法的實(shí)現(xiàn)
void method_invoke_stret ( id receiver, Method m, ... );
// 獲取方法名
SEL method_getName ( Method m );
// 返回方法的實(shí)現(xiàn)
IMP method_getImplementation ( Method m );
// 獲取描述方法參數(shù)和返回值類型的字符串
const char * method_getTypeEncoding ( Method m );
// 獲取方法的返回值類型的字符串
char * method_copyReturnType ( Method m );
// 獲取方法的指定位置參數(shù)的類型字符串
char * method_copyArgumentType ( Method m, unsigned int index );
// 通過(guò)引用返回方法的返回值類型字符串
void method_getReturnType ( Method m, char *dst, size_t dst_len );
// 返回方法的參數(shù)的個(gè)數(shù)
unsigned int method_getNumberOfArguments ( Method m );
// 通過(guò)引用返回方法指定位置參數(shù)的類型字符串
void method_getArgumentType ( Method m, unsigned int index, char *dst, size_t dst_len );
// 返回指定方法的方法描述結(jié)構(gòu)體
struct objc_method_description * method_getDescription ( Method m );
// 設(shè)置方法的實(shí)現(xiàn)
IMP method_setImplementation ( Method m, IMP imp );
// 交換兩個(gè)方法的實(shí)現(xiàn)
void method_exchangeImplementations ( Method m1, Method m2 );
```
上面這些函數(shù)在通過(guò)Runtime實(shí)現(xiàn)一些東西的時(shí)候或者在看別人的代碼的時(shí)候或許能用到念赶,只需要知道有這么一些函數(shù)就可以了。

###Class
Class在我的一篇文章中有詳細(xì)的講解恰力,請(qǐng)移步[OC中的類是怎么來(lái)的叉谜?](),這里不在贅訴了。

###_cmd
通過(guò)_cmd這個(gè)關(guān)鍵字能獲取當(dāng)前方法的`SEL`踩萎⊥>郑看個(gè)栗子吧:
```
- (void)testCmd {
    SEL currentMethodSel = _cmd;
    NSLog(@"currentSel is :%s",(char *)currentMethodSel); 
}
```
上面的打印結(jié)果為:
```
currentSel is :testCmd
```

###objc_msgSend
在OC中,對(duì)方法的調(diào)用被稱之為發(fā)送消息驻民。其實(shí)我們對(duì)方法的調(diào)用最后都會(huì)被編譯為下面的這種形式:
>對(duì)于函數(shù):

```
[target method1];
[target method2:var];
```

>沒(méi)有參數(shù):

```
objc_msgSend(target,@selector(method1));
```

>有參數(shù):

```
objc_msgSend(target,@selector(method2:),var);
```
方法的調(diào)用過(guò)程在我的上一篇文章[OC中的類是怎么來(lái)的翻具?]()

###結(jié)尾
有人說(shuō)Runtime是OC的本質(zhì)和精華,雖然我們?cè)陧?xiàng)目中不經(jīng)常用回还,但是理解還是有很大的用處的裆泳。喜歡我的文章就給我鼓勵(lì)吧!
![](http://upload-images.jianshu.io/upload_images/465386-2f3e022157448deb.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/200)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柠硕,一起剝皮案震驚了整個(gè)濱河市工禾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蝗柔,老刑警劉巖闻葵,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異癣丧,居然都是意外死亡槽畔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)胁编,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)厢钧,“玉大人鳞尔,你說(shuō)我怎么就攤上這事≡缰保” “怎么了寥假?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)霞扬。 經(jīng)常有香客問(wèn)我糕韧,道長(zhǎng),這世上最難降的妖魔是什么喻圃? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任萤彩,我火速辦了婚禮,結(jié)果婚禮上斧拍,老公的妹妹穿的比我還像新娘乒疏。我一直安慰自己,他們只是感情好饮焦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著窍侧,像睡著了一般县踢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上伟件,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天硼啤,我揣著相機(jī)與錄音,去河邊找鬼斧账。 笑死谴返,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咧织。 我是一名探鬼主播嗓袱,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼习绢!你這毒婦竟也來(lái)了渠抹?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤闪萄,失蹤者是張志新(化名)和其女友劉穎梧却,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體败去,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡放航,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了圆裕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片广鳍。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡荆几,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搜锰,到底是詐尸還是另有隱情伴郁,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布蛋叼,位于F島的核電站焊傅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏狈涮。R本人自食惡果不足惜狐胎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歌馍。 院中可真熱鬧握巢,春花似錦、人聲如沸松却。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)晓锻。三九已至歌焦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砚哆,已是汗流浹背独撇。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留躁锁,地道東北人纷铣。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像战转,于是被迫代替她去往敵國(guó)和親搜立。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉匣吊,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,719評(píng)論 0 9
  • 我們常常會(huì)聽(tīng)說(shuō) Objective-C 是一門(mén)動(dòng)態(tài)語(yǔ)言儒拂,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,195評(píng)論 0 7
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,560評(píng)論 33 466
  • Runtime是什么 Runtime 又叫運(yùn)行時(shí)色鸳,是一套底層的 C 語(yǔ)言 API社痛,其為 iOS 內(nèi)部的核心之一,我...
    SuAdrenine閱讀 878評(píng)論 0 3
  • 明天就是父親節(jié)了命雀,距離父親離開(kāi)人世已經(jīng)三年蒜哀,在父親節(jié)就要到來(lái)的日子,在六月艷陽(yáng)高照的日子,女兒在鐘山腳下的...
    風(fēng)鈴_bb0d閱讀 483評(píng)論 7 6