CLASS , SEL, IMP

原文鏈接:關(guān)于CLASS

cocoa當(dāng)中的函數(shù)調(diào)用,是一種以消息的方式進(jìn)行的函數(shù)調(diào)用纲辽,這一點(diǎn)與C++啦吧,java是有很大差別的您觉。因此該類型的理解,會(huì)涉及到三個(gè)重要的概念授滓,class琳水,sel,IMP般堆。

class

每個(gè)NSObject的第一個(gè)成員變量都是class類型的成員在孝,isa,這個(gè)isa的對(duì)象可以訪問到本類的父類淮摔,也可以訪問到本類的所有方法的列表私沮。

含義

Class 被定義為一個(gè)指向 objc_class的結(jié)構(gòu)體指針,這個(gè)結(jié)構(gòu)體表示每一個(gè)類的類結(jié)構(gòu)和橙。而 objc_class 在objc/objc_class.h中定義如下:

struct objc_class {

struct objc_class super_class;? /*父類*/

const char *name;? ? ? ? ? ? ? ? /*類名字*/

long version;? ? ? ? ? ? ? ? ? /*版本信息*/

long info;? ? ? ? ? ? ? ? ? ? ? ? /*類信息*/

long instance_size;? ? ? ? ? ? ? /*實(shí)例大小*/

struct objc_ivar_list *ivars;? ? /*實(shí)例參數(shù)鏈表*/

struct objc_method_list **methodLists;? /*方法鏈表*/

struct objc_cache *cache;? ? ? ? ? ? ? /*方法緩存*/

struct objc_protocol_list *protocols;? /*協(xié)議鏈表*/

};

由此可見仔燕,Class 是指向類結(jié)構(gòu)體的指針,該類結(jié)構(gòu)體含有一個(gè)指向其父類類結(jié)構(gòu)的指針魔招,該類方法的鏈表晰搀,該類方法的緩存以及其他必要信息。

NSObject 的class 方法就返回這樣一個(gè)指向其類結(jié)構(gòu)的指針办斑。每一個(gè)類實(shí)例對(duì)象的第一個(gè)實(shí)例變量是一個(gè)指向該對(duì)象的類結(jié)構(gòu)的指針外恕,叫做isa。通過該指針乡翅,對(duì)象可以訪問它對(duì)應(yīng)的類以及相應(yīng)的父類鳞疲。如圖一所示:

如圖一所示,圓形所代表的實(shí)例對(duì)象的第一個(gè)實(shí)例變量為 isa蠕蚜,它指向該類的類結(jié)構(gòu) The object’s class尚洽。而該類結(jié)構(gòu)有一個(gè)指向其父類類結(jié)構(gòu)的指針superclass, 以及自身消息名稱(selector)/實(shí)現(xiàn)地址(address)的方法鏈表波势。

方法的含義:

注意這里所說的方法鏈表里面存儲(chǔ)的是Method 類型的翎朱。圖一中selector 就是指 Method的 SEL,? address就是指Method的 IMP。 Method 在頭文件 objc_class.h中定義如下:

typedef struct objc_method *Method;

typedef struct objc_ method {

SEL method_name;

char *method_types;

IMP method_imp;

};

一個(gè)方法 Method尺铣,其包含一個(gè)方法選標(biāo) SEL – 表示該方法的名稱拴曲,一個(gè)types – 表示該方法參數(shù)的類型,一個(gè) IMP? - 指向該方法的具體實(shí)現(xiàn)的函數(shù)指針凛忿。

SEL

這個(gè)是方法名稱的描述澈灼。

在前面我們看到方法選標(biāo) SEL 的定義為:

typedef struct objc_selector? *SEL;

它是一個(gè)指向 objc_selector 指針,表示方法的名字/簽名。如下所示叁熔,打印出 selector委乌。

-(NSInteger)maxIn:(NSInteger)a theOther:(NSInteger)b

{

return (a > b) ? a : b;

}

NSLog(@"SEL=%s", @selector(maxIn:theOther:));

輸出:SEL=maxIn:theOther:

不同的類可以擁有相同的 selector,這個(gè)沒有問題荣回,因?yàn)椴煌惖膶?shí)例對(duì)象performSelector相同的 selector 時(shí)遭贸,會(huì)在各自的消息選標(biāo)(selector)/實(shí)現(xiàn)地址(address) 方法鏈表中根據(jù) selector 去查找具體的方法實(shí)現(xiàn)IMP, 然后用這個(gè)方法實(shí)現(xiàn)去執(zhí)行具體的實(shí)現(xiàn)代碼。這是一個(gè)動(dòng)態(tài)綁定的過程心软,在編譯的時(shí)候壕吹,我們不知道最終會(huì)執(zhí)行哪一些代碼,只有在執(zhí)行的時(shí)候删铃,通過selector去查詢耳贬,我們才能確定具體的執(zhí)行代碼。

IMP

這個(gè)是具體的方法的地址猎唁。

在前面我們也看到 IMP 的定義為:

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

根據(jù)前面id 的定義咒劲,我們知道 id是一個(gè)指向 objc_object 結(jié)構(gòu)體的指針,該結(jié)構(gòu)體只有一個(gè)成員isa诫隅,所以任何繼承自 NSObject 的類對(duì)象都可以用id 來指代腐魂,因?yàn)?NSObject 的第一個(gè)成員實(shí)例就是isa。

至此阎肝,我們就很清楚地知道 IMP? 的含義:IMP 是一個(gè)函數(shù)指針挤渔,這個(gè)被指向的函數(shù)包含一個(gè)接收消息的對(duì)象id(self? 指針), 調(diào)用方法的選標(biāo) SEL (方法名),以及不定個(gè)數(shù)的方法參數(shù)风题,并返回一個(gè)id。也就是說 IMP 是消息最終調(diào)用的執(zhí)行代碼嫉父,是方法真正的實(shí)現(xiàn)代碼 沛硅。我們可以像在C語言里面一樣使用這個(gè)函數(shù)指針。

NSObject 類中的methodForSelector:方法就是這樣一個(gè)獲取指向方法實(shí)現(xiàn)IMP 的指針绕辖,methodForSelector:返回的指針和賦值的變量類型必須完全一致摇肌,包括方法的參數(shù)類型和返回值類型。

下面的例子展示了怎么使用指針來調(diào)用setFilled:的方法實(shí)現(xiàn):

void (*setter)(id, SEL, BOOL);

int i;

setter = (void(*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];

for (i = 0; i < 1000; i++)

setter(targetList[i], @selector(setFilled:), YES);

使用methodForSelector:來避免動(dòng)態(tài)綁定將減少大部分消息的開銷仪际,但是這只有在指定的消息被重復(fù)發(fā)送很多次時(shí)才有意義围小,例如上面的for循環(huán)。

注意树碱,methodForSelector:是Cocoa運(yùn)行時(shí)系統(tǒng)的提供的功能肯适,而不是Objective-C語言本身的功能。

幾個(gè)重要的輔助函數(shù)成榜,可以在使用過程中起到很好的輔助作用框舔,尤其是在動(dòng)態(tài)編譯等起到了比較大的作用。

我們可以通過NSObject的一些方法獲取運(yùn)行時(shí)信息或動(dòng)態(tài)執(zhí)行一些消息:

class? 返回對(duì)象的類;

isKindOfClass 和 isMemberOfClass檢查對(duì)象是否在指定的類繼承體系中刘绣;

respondsToSelector 檢查對(duì)象能否相應(yīng)指定的消息樱溉;

conformsToProtocol 檢查對(duì)象是否實(shí)現(xiàn)了指定協(xié)議類的方法;

methodForSelector? 返回指定方法實(shí)現(xiàn)的地址纬凤。

performSelector:withObject 執(zhí)行SEL 所指代的方法福贞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市停士,隨后出現(xiàn)的幾起案子肚医,更是在濱河造成了極大的恐慌,老刑警劉巖向瓷,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肠套,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡猖任,警方通過查閱死者的電腦和手機(jī)你稚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朱躺,“玉大人刁赖,你說我怎么就攤上這事〕げ螅” “怎么了宇弛?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)源请。 經(jīng)常有香客問我枪芒,道長(zhǎng),這世上最難降的妖魔是什么谁尸? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任舅踪,我火速辦了婚禮,結(jié)果婚禮上良蛮,老公的妹妹穿的比我還像新娘抽碌。我一直安慰自己,他們只是感情好决瞳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布货徙。 她就那樣靜靜地躺著,像睡著了一般皮胡。 火紅的嫁衣襯著肌膚如雪痴颊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天胸囱,我揣著相機(jī)與錄音祷舀,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛裳扯,可吹牛的內(nèi)容都是我干的抛丽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饰豺,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼亿鲜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起冤吨,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤蒿柳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后漩蟆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垒探,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年怠李,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了圾叼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捺癞,死狀恐怖夷蚊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情髓介,我是刑警寧澤惕鼓,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站唐础,受9級(jí)特大地震影響箱歧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜彻犁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一叫胁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汞幢,春花似錦、人聲如沸微谓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豺型。三九已至仲智,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姻氨,已是汗流浹背钓辆。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人前联。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓功戚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親似嗤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子啸臀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評(píng)論 0 9
  • cocoa當(dāng)中的函數(shù)調(diào)用烁落,是一種以消息的方式進(jìn)行的函數(shù)調(diào)用乘粒,這一點(diǎn)與C++,java是有很大差別的伤塌。因此該類型的理...
    夬大爺閱讀 376評(píng)論 0 0
  • 參考鏈接: http://www.cnblogs.com/ioshe/p/5489086.html 簡(jiǎn)介 Runt...
    樂樂的簡(jiǎn)書閱讀 2,135評(píng)論 0 9
  • 繼上Runtime梳理(四) 通過前面的學(xué)習(xí)灯萍,我們了解到Objective-C的動(dòng)態(tài)特性:Objective-C不...
    小名一峰閱讀 752評(píng)論 0 3
  • 本文轉(zhuǎn)載自:http://yulingtianxia.com/blog/2014/11/05/objective-...
    ant_flex閱讀 758評(píng)論 0 1