OC中 Self 與 Super 的區(qū)別

前奏

self 是什么翁巍? super 是什么趴腋?
  動(dòng)態(tài)方法中:self 是代表 “對(duì)象”,
  靜態(tài)方法中:self 是代表 “類(lèi)”鳖链。
  self 就代表當(dāng)前方法的調(diào)用者呢袱,
  super 相當(dāng)于調(diào)用父類(lèi)的方法官扣。
這個(gè)例子我就不寫(xiě)了。

如果在 init 中調(diào)用 self 和 super 是否會(huì)有不同羞福?

新建一個(gè)類(lèi)叫 Son 繼承 NSObject

- (id)init {
    if (self = [super init] ) {
        
        NSLog(@"%@", NSStringFromClass([self class])); // Son
        NSLog(@"%@", NSStringFromClass([super class])); // Son
        NSLog(@"%@", NSStringFromClass([self superclass])); // Son
    }
    return self;
}

結(jié)果如下

  2017-09-24 13:25:11.109332+0800 Demo[22406:879505] Son
  2017-09-24 13:25:11.109567+0800 Demo[22406:879505] Son
  2017-09-24 13:25:11.109681+0800 Demo[22406:879505] NSObject
  • [self class] 和 [super class] 為什么輸出的類(lèi)型 是一樣的惕蹄?

為什么?

  • self 是類(lèi)隱藏的參數(shù)治专,指向當(dāng)前調(diào)用方法的類(lèi)卖陵,另外一個(gè)隱藏參數(shù)是_cmd,代表當(dāng)前類(lèi)方法的 selector张峰。
  • super 并不是隱藏參數(shù)泪蔫,只是一個(gè) “編譯器指示符”,它和 self 指向的是相同的消息接收者喘批。所以上面不論是 [self class] 和 [super class] 輸出的類(lèi)型是一樣的撩荣。
  • 不同之處: super 會(huì)告訴編譯器,當(dāng)調(diào)用 setXXX 的方法時(shí)谤祖,要去調(diào)用父類(lèi)的方法婿滓,而不是本類(lèi)的。self 會(huì)從當(dāng)前類(lèi)的方法列表中開(kāi)始找粥喜,沒(méi)有的話再去父類(lèi)中找凸主。
又做了一個(gè)實(shí)驗(yàn):
  • 又創(chuàng)建了一個(gè)繼承于 Son 的類(lèi) 叫 Bom
  • 分別在 Son 和 Bom 實(shí)現(xiàn)了一個(gè) + 號(hào)方法 eat。
  • 在 Bom 的 init 方法里面寫(xiě)以下代碼
- (id)init {
    if (self = [super init]) {
        [[super superclass] eat];
        [[self superclass] eat];
        [[super class] eat];
        [[self class] eat];
    }
    return self;
}
  • 輸出為下面

    2017-09-25 09:32:36.390684+0800 Demo[31497:1089563] 執(zhí)行了 Son 的 class
    2017-09-25 09:32:36.390756+0800 Demo[31497:1089563] 執(zhí)行了 Son 的 class
    2017-09-25 09:32:36.390838+0800 Demo[31497:1089563] 執(zhí)行了 Bom 的 class
    2017-09-25 09:32:36.390920+0800 Demo[31497:1089563] 執(zhí)行了 Bom 的 class
    
  • 結(jié)果和我們得到的結(jié)論是一模一樣的额湘。

原理:

  • 這種機(jī)制底層是怎么回事卿吐?

    • Apple 是這樣說(shuō)的
      When it encounters a method invocation, the compiler might generate a call to any of several functions to perform the actual message dispatch, depending on the receiver, the return value, and the arguments. You can use these functions to dynamically invoke methods from your own plain C code, or to use argument forms not permitted by NSObject’s perform… methods. These functions are declared in /usr/include/objc/objc-runtime.h.

      objc_msgSend sends a message with a simple return value to an instance of a class.

      objc_msgSend_stret sends a message with a data-structure return value to an instance of a class.

      objc_msgSendSuper sends a message with a simple return value to the superclass of an instance of a class.

      objc_msgSendSuper_stret sends a message with a data-structure return value to the superclass of an instance of a class.

  • 這里我們只需要關(guān)注 以下兩個(gè)方法

    id objc_msgSend(id theReceiver, SEL theSelector, ...) 
    id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 
    

msgSend 方法

  • id theReceiver :消息接收者旁舰。

  • SEL theSelector:調(diào)用具體類(lèi)方法的 selector

    [self setXXX]; 編譯器會(huì)替換成 objc_msgSend 的函數(shù)調(diào)用。消息的接收者是 self嗡官,所有后面的 selector 會(huì)從當(dāng)前 self 的方法表里面找 setXXX箭窜,找到后把對(duì)應(yīng)的 selector 傳過(guò)去。

msgSendSuper 方法

  • struct objc_super :是 objc_super 的結(jié)構(gòu)體

  • super, SEL op :類(lèi)似于 selector

    struct objc_super 結(jié)構(gòu)體如下

    struct objc_super {  
      id receiver;  
     Class superClass;  
    }; 
    
    • receiver 相當(dāng)于消息接收者
    • Class superClass 相當(dāng)于父類(lèi)衍腥,比如在上面的例子 Bom 中調(diào)用 就是他的父類(lèi) Son

大概機(jī)制就這樣了磺樱。

總結(jié):

  • 比如在 Bom 中調(diào)用 [self class]
    使用 objc_msgSend 第一個(gè)參數(shù)是 self 也就是 Bom *bom 這個(gè)實(shí)例。
    第二個(gè)參數(shù) 找到這個(gè) class 的 selector婆咸。 先去 Bom 這個(gè)類(lèi)去找竹捉,沒(méi)有就去父類(lèi) Son 中找, 也沒(méi)有的話尚骄, 就去 Son 的父類(lèi) NSObject 中找块差,最終在 NSObject 中找到了 這個(gè) class 方法, 然后 返回 receiver 類(lèi)別倔丈, 所以輸出 為 Bom憨闰,

  • 當(dāng)調(diào)用的是 [super class]
    使用 objc_msgSendSuper 的方法
    第一個(gè)參數(shù):結(jié)構(gòu)體

    • 第一個(gè)成員變量: self
    • 第二個(gè)成員變量:Son
      第二個(gè)參數(shù):去 superClass(Son) 中找 class 方法,沒(méi)有需五,然后去NSObject 中找鹉动,找到了, 然后內(nèi)部使用函數(shù) objc_msgSend(objc_super->receiver, @selector(class)) 去調(diào)用宏邮,這樣就和上面的 [self class] 調(diào)用相同了训裆。所以 此時(shí)的 receiver 還是 Bom *bom,所以返回的也是 Bom蜀铲。

有錯(cuò)誤的理解歡迎指出。共同進(jìn)步属百!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末记劝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子族扰,更是在濱河造成了極大的恐慌厌丑,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渔呵,死亡現(xiàn)場(chǎng)離奇詭異怒竿,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)扩氢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)耕驰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人录豺,你說(shuō)我怎么就攤上這事朦肘》构” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵媒抠,是天一觀的道長(zhǎng)弟断。 經(jīng)常有香客問(wèn)我,道長(zhǎng)趴生,這世上最難降的妖魔是什么阀趴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮苍匆,結(jié)果婚禮上刘急,老公的妹妹穿的比我還像新娘。我一直安慰自己锉桑,他們只是感情好排霉,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著民轴,像睡著了一般攻柠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上后裸,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天瑰钮,我揣著相機(jī)與錄音,去河邊找鬼微驶。 笑死浪谴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的因苹。 我是一名探鬼主播苟耻,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼扶檐!你這毒婦竟也來(lái)了凶杖?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤款筑,失蹤者是張志新(化名)和其女友劉穎智蝠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奈梳,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杈湾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了攘须。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漆撞。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出叫挟,到底是詐尸還是另有隱情艰匙,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布抹恳,位于F島的核電站员凝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏奋献。R本人自食惡果不足惜健霹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓶蚂。 院中可真熱鬧糖埋,春花似錦、人聲如沸窃这。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杭攻。三九已至祟敛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兆解,已是汗流浹背馆铁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锅睛,地道東北人埠巨。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像现拒,于是被迫代替她去往敵國(guó)和親辣垒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉印蔬,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,679評(píng)論 0 9
  • 兩瓶熱水冷卻的時(shí)間恰好 是你打完點(diǎn)滴的時(shí)間 是的乍构,恰好 早春二月的冷暖有別于冬日的嚴(yán)寒 夢(mèng)想春的枝頭 有少女時(shí)的靦...
    江城妖怪閱讀 136評(píng)論 3 1
  • 今天是我裸辭的第28天。 3月已接近尾聲扛点,我的工作已經(jīng)空窗快1個(gè)月了,這是我從2012年3月實(shí)習(xí)以來(lái)休的最長(zhǎng)時(shí)間的...
    桃筱夭閱讀 289評(píng)論 0 0
  • 今天晨讀介紹的書(shū)名我很喜歡,人生總會(huì)有辦法奥帘。 有時(shí)候人們往往會(huì)思維慣性铜邮,糾結(jié)著一個(gè)問(wèn)題不放,但是往往得到的答案卻不...
    奔跑的丸子啊閱讀 409評(píng)論 2 49
  • 我想為你唱支歌,姑娘 夜色美好松蒜,如你一般模樣 你在那個(gè)城市過(guò)得好么扔茅,姑娘 會(huì)不會(huì)有人撫慰你的憂傷 我過(guò)得挺不錯(cuò)的,...
    知亦不知閱讀 191評(píng)論 0 0