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)看到了SEL和IMP,說明SEL和IMP其實都是Method的屬性。
我們接著來看SEL。
SEL
還是先看定義
Objc.h
/// An opaque type that represents a method selector.代表一個方法的不透明類型
typedef struct objc_selector *SEL;
這里要先說明下selector和SEL的關(guān)系,我在寫本文的時候,其實搜索的是selector,直到我看到了selector的定義,才發(fā)現(xiàn)我理解一直不對。
@property SEL selector;
在文檔中,selector的定義都是這樣聲明,也就是說:selector是SEL的一個實例,只是在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通過selector和IMP兩個屬性,實現(xiàn)了快速查詢方法及實現(xiàn),相對提高了性能,又保持了靈活性。
更多:iOS面試題合集