iOS面試題:SEL和Method和IMP分別說下再談下對IMP的理解?

Method

先看下定義

runtime.h
/// An opaque type that represents a method in a class definition.代表類定義中一個方法的不透明類型
typedef struct objc_method *Method;

struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
} 

Method和我們平時理解的函數(shù)是一致的,就是表示能夠獨立完成一個功能的一段代碼,比如:

- (void)logName
{
    NSLog(@"name");
} 

這段代碼,就是一個函數(shù)。

我們來看下objc_method這個結(jié)構(gòu)體的內(nèi)容:

  • SEL method_name 方法名
  • char *method_types 方法類型
  • IMP method_imp 方法實現(xiàn)

在這個結(jié)構(gòu)體重,我們已經(jīng)看到了SELIMP,說明SELIMP其實都是Method的屬性。

我們接著來看SEL

SEL

還是先看定義

Objc.h
/// An opaque type that represents a method selector.代表一個方法的不透明類型
typedef struct objc_selector *SEL;

這里要先說明下selectorSEL的關(guān)系,我在寫本文的時候,其實搜索的是selector,直到我看到了selector的定義,才發(fā)現(xiàn)我理解一直不對。

@property SEL selector;

在文檔中,selector的定義都是這樣聲明,也就是說:selectorSEL的一個實例,只是在iOS中,selector的使用是如此的頻繁,我們才會把他當成一個概念。

selector怎么理解呢?我們可以想想股票,比如市場上有如此多公司在納斯達克上市,而且他們的名字又非常的長,或者有些公司的名稱也是相似的,都是**有限公司。那當市場去指定一個股票的時候,效率會非常低,當你著急想買股票的時候,你會跟你的經(jīng)紀人說:“hi,peter,給我買一百股Tuniu limited liability company的股票嗎?”,也許等你說完,經(jīng)紀人輸入完,市場就變化了,所以納斯達克通常用代碼,比如“TOUR”.這里的selector有類似的作用,就是讓我們能夠快速找到對應(yīng)的函數(shù)。

文檔中是這樣講的:

A method selector is a C string that has been registered (or “mapped“) with the Objective-C runtime. Selectors generated by the compiler are automatically mapped by the runtime when the class is loaded.

在iOS中,runtime會在運行的時候,通過load函數(shù),將所有的methodhash然后map到set中。這樣在運行的時候,尋找selector的速度就會非常快,不會因為runtime特性犧牲太多的性能。

selector既然是一個string,我覺得應(yīng)該是類似className+method的組合,命名規(guī)則有兩條:

  • 同一個類,selector不能重復
  • 不同的類,selector可以重復

這也帶來了一個弊端,我們在寫C代碼的時候,經(jīng)常會用到函數(shù)重載,就是函數(shù)名相同,參數(shù)不同,但是這在Objective-C中是行不通的,因為selector只記了method的name,沒有參數(shù),所以沒法區(qū)分不同的method。

比如:

- (void)caculate(NSInteger)num;

- (void)caculate(CGFloat)num;

是會報錯的。

我們只能通過命名來區(qū)別:

- (void)caculateWithInt(NSInteger)num;

- (void)caculateWithFloat(CGFloat)num;

IMP

看下IMP的定義

/// A pointer to the function of a method implementation.  指向一個方法實現(xiàn)的指針
typedef id (*IMP)(id, SEL, ...); 
#endif

這個就比較好理解了,就是指向最終實現(xiàn)程序的內(nèi)存地址的指針。

綜上,在iOS的runtime中,Method通過selectorIMP兩個屬性,實現(xiàn)了快速查詢方法及實現(xiàn),相對提高了性能,又保持了靈活性。


更多:iOS面試題合集

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

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,030評論 0 9
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,621評論 1 32
  • 繼上Runtime梳理(四) 通過前面的學習,我們了解到Objective-C的動態(tài)特性:Objective-C不...
    小名一峰閱讀 838評論 0 3
  • 轉(zhuǎn)載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 827評論 0 2
  • 我們常常會聽說 Objective-C 是一門動態(tài)語言,那么這個「動態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,319評論 0 7

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