runtime 如何通過 selector 找到對應(yīng)的 IMP 地址捅彻?

實例方法類方法的存儲位置:

  • 實例方法:每個實例的isa指針指向著對應(yīng)類對象劲绪,而每一個類對象中都一個對象方法列表。
  • 類方法:每個類對象的isa指針都指向著對應(yīng)的元類對象卡者,而每一個元類對象中都有一個類方法列表蒿囤。
  • 當我們發(fā)送一個消息給一個NSObject對象時,這條消息會在對象的類對象方法列表里查找崇决。
  • 當我們發(fā)送一個消息給一個類時材诽,這條消息會在類的meta class對象的方法列表里查找底挫。
  • 方法列表中記錄著一個個方法實體(結(jié)構(gòu)體Method),實體中包含方法的名稱脸侥,方法實現(xiàn)建邓,以及參數(shù)類型。
  • 其實selector本質(zhì)就是C字符串的方法名稱(見下面分析)湿痢,通過這個方法名稱就可以在方法列表中找到方法實體涝缝,進一步找到對應(yīng)的方法實現(xiàn)扑庞。

Selector譬重,Method 和 IMP 的區(qū)別與聯(lián)系

Selector
定義:

typedef struct objc_selector *SEL

翻譯成中文叫做選擇子或者選擇器,選擇子代表方法在Runtime期間的標識符罐氨。為SEL類型臀规,雖然SELobjc_selector結(jié)構(gòu)體指針,但實際上它只是一個C字符串栅隐。在類加載的時候塔嬉,編譯器會生成與方法相對應(yīng)的選擇子,并注冊到Objective-CRuntime運行系統(tǒng)租悄。

常見的有兩種方式來獲取/創(chuàng)建選擇子:

SEL selA = @selector(setString:);
SEL selB = sel_registerName("setString:"); 

在控制臺測試:

(lldb) p selA
(SEL) $1 = "setString:"
(lldb) p selB
(SEL) $2 = "setString:"

兩者打印出來的都是字符串谨究。

我們從sel_getName()方法的源碼可以看出SELconst char *是可以相互轉(zhuǎn)化的:

const char *sel_getName(SEL sel) {
   return sel ? (const char *)sel : "<null selector>";
}

如果將selAselB強轉(zhuǎn)為為const char *

(lldb) p (const char *)$2
(const char *) $3 = 0x00007fff9a3794b5 "setString:"
(lldb) p (const char *)$1
(const char *) $4 = 0x00007fff9a3794b5 "setString:"
(lldb) 

上面的結(jié)果可以看出,selAselB指向相同的地址泣棋,代表同一個字符串胶哲。

如果某個類實現(xiàn)了setString:方法,那么以上兩個選擇子傳入 respondsToSelector()方法返回的結(jié)果都將為YES潭辈。

不同類中相同名字的方法所對應(yīng)的方法選擇子是相同的鸯屿。

Implementation(IMP):
定義:

typedef id (*IMP)(id, SEL, ...)

代表函數(shù)指針,即函數(shù)執(zhí)行的入口把敢。該函數(shù)使用標準的C調(diào)用寄摆。

  • 第一個參數(shù)指向self(它代表當前類實例的地址,如果是類則指向的是它的元類)修赞,作為消息的接受者婶恼;
  • 第二個參數(shù)代表方法的選擇子;
  • ...代表可選參數(shù)柏副;
  • 前面的id代表返回值熙尉。

Method
定義:

typedef struct objc_method *Method

Method 對開發(fā)者來說是一種不透明的類型,它是一個objc_method結(jié)構(gòu)體指針搓扯,objc_method的定義為:

/// An opaque type that represents a method in a class definition.
    typedef struct objc_method *Method;

    struct objc_method {
        SEL method_name;  // 方法選擇器检痰。
        char *method_types;  // 存儲著方法的參數(shù)類型和返回值類型。
        IMP method_imp;  // 函數(shù)指針锨推。
    } 
  • 方法名method_name類型為SEL,前面提到過相同名字的方法即使在不同類中定義换薄,它們的方法選擇器也相同踢京;
  • 方法類method_types是個char指針,其實存儲著方法的參數(shù)類型和返回值類型厦幅,即是Type Encoding編碼;
  • method_imp指向方法的實現(xiàn)慨飘,本質(zhì)上是一個函數(shù)的指針确憨,就是前面講到的Implementation

Selector瓤的,Method休弃,IMP它們之間的關(guān)系可以這么解釋:
一個類(Class)持有一個方法列表,在運行期分發(fā)消息圈膏,表中的每一個實體代表一個方法(Method)塔猾,它的名字叫做選擇子(SEL),對應(yīng)著一種方法實現(xiàn)(IMP稽坤。


iOS面試題匯總

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丈甸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子尿褪,更是在濱河造成了極大的恐慌睦擂,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杖玲,死亡現(xiàn)場離奇詭異顿仇,居然都是意外死亡,警方通過查閱死者的電腦和手機天揖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門夺欲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人今膊,你說我怎么就攤上這事些阅。” “怎么了斑唬?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵市埋,是天一觀的道長。 經(jīng)常有香客問我恕刘,道長缤谎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任褐着,我火速辦了婚禮坷澡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘含蓉。我一直安慰自己频敛,他們只是感情好项郊,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斟赚,像睡著了一般着降。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拗军,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天任洞,我揣著相機與錄音,去河邊找鬼发侵。 笑死交掏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的器紧。 我是一名探鬼主播耀销,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼楼眷,長吁一口氣:“原來是場噩夢啊……” “哼铲汪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起罐柳,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤掌腰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后张吉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體齿梁,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年肮蛹,在試婚紗的時候發(fā)現(xiàn)自己被綠了勺择。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡伦忠,死狀恐怖省核,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昆码,我是刑警寧澤气忠,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站赋咽,受9級特大地震影響旧噪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脓匿,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一淘钟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陪毡,春花似錦米母、人聲如沸袱瓮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尺借。三九已至,卻和暖如春精拟,著一層夾襖步出監(jiān)牢的瞬間燎斩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工蜂绎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留栅表,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓师枣,卻偏偏與公主長得像怪瓶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子践美,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

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