一萬(wàn)小時(shí)定律的遺憾之Objective-C的self與super

Malcolm T.Gladwell說(shuō):“人們眼中的天才之所以卓越非凡险绘,并非天資超人一等,而是付出了持續(xù)不斷的努力。1萬(wàn)小時(shí)的錘煉是任何人從平凡變成超凡的必要條件帆疟。”

對(duì)于一萬(wàn)小時(shí)定律宇立,我是深信不疑的踪宠,然而真的嘗試做著的時(shí)候,才發(fā)現(xiàn)一萬(wàn)小時(shí)妈嘹,對(duì)于天資愚鈍的我還遠(yuǎn)遠(yuǎn)不夠柳琢。

學(xué)習(xí)Objective-C已近兩年,每天的工作學(xué)習(xí)的平均時(shí)間也控制在十個(gè)小時(shí)以上润脸,漸漸地一直以為自己對(duì)其機(jī)制及語(yǔ)法有了一定認(rèn)識(shí)柬脸,然而看到別人對(duì)兩個(gè)編程中最常用到關(guān)鍵字self、super的理解的時(shí)候毙驯,實(shí)在羞愧倒堕,深感自己對(duì)平日使用的東西了解還太少太少。

super.jpg

正文

當(dāng)然爆价,這一切都要從一個(gè)Model和一個(gè)網(wǎng)上的筆試題說(shuō)起:

1垦巴、一個(gè)Model
#import <Foundation/Foundation.h>

@interface EVNHelper : NSObject
- (instancetype)init;
@end

#import "EVNHelper.h"

@implementation EVNHelper

- (instancetype)init
{
    self = [super init];// ?允坚?魂那?
    if (self)
    {
       // other init code 
    }
    return self;
}
@end
2、 一個(gè)筆試題
- (instancetype)init
{
    self = [super init]; 
    if (self)
    {
        NSLog(@"self className is %@", NSStringFromClass([self class]));
        NSLog(@"super  className is %@", NSStringFromClass([super class]));

        NSLog(@"self superclass  className is %@", NSStringFromClass([self superclass]));
        NSLog(@"super superclass  className is %@", NSStringFromClass([super superclass]));
    }
    return self;
}
@end

輸出:
    2016-12-24 16:04:32.600 Demo[6009:1006834] self className is EVNHepler
    2016-12-24 16:04:32.601 Demo[6009:1006834] super  className is EVNHepler
    2016-12-24 16:04:32.601 Demo[6009:1006834] self superclass  className is NSObject
    2016-12-24 16:04:32.602 Demo[6009:1006834] super superclass  className is NSObject

對(duì)應(yīng)的問(wèn)題也來(lái)了:

1稠项、子類初始化為什么要寫self = [super init]涯雅,意義?
2展运、為什么[self class]和 [super class]活逆;[self superclass]和[super superclass]輸出相同精刷?

可到底self和super是什么呢?(由于對(duì)runtime懂得太少蔗候,怕誤人子弟怒允,暫不扯底層代碼,只說(shuō)自己能看到的)

  • self
    之前我的理解锈遥,self是對(duì)象指針纫事,指向當(dāng)前類的實(shí)例對(duì)象。其實(shí)這種理解是不準(zhǔn)確的所灸,因?yàn)樵陟o態(tài)方法self 依然可以使用(如下代碼)丽惶,這怎么解釋呢!
+ (void)helperMethodA
{
    [self helperMethodB];
}
+ (void)helperMethodB
{
    NSLog(@"asdfasdfasd");
}

帶著這份好奇爬立,最終我在NSObject協(xié)議中找到了self钾唬,原來(lái)self是返回instancetype類型的代理方法,但又有些奇怪侠驯,我們?cè)谧远x子類的時(shí)候并沒(méi)有實(shí)現(xiàn)這個(gè)方法抡秆,我認(rèn)為self的功能,OC已經(jīng)幫我們實(shí)現(xiàn)吟策,只是我們看不到而已儒士。這樣就明確了,self最終返回的結(jié)果就是instancetype類型的東西檩坚,它是動(dòng)態(tài)類型乍桂,最終運(yùn)行時(shí)才會(huì)確定,實(shí)例方法返回實(shí)例類型效床、靜態(tài)方法返回的是Class睹酌。

#include <objc/objc.h>
#include <objc/NSObjCRuntime.h>

@class NSString, NSMethodSignature, NSInvocation;
@protocol NSObject

- (BOOL)isEqual:(id)object;
@property (readonly) NSUInteger hash;
@property (readonly) Class superclass;
......
- (Class)class OBJC_SWIFT_UNAVAILABLE("use 'anObject.dynamicType' instead");
- (instancetype)self;
......
@end

  • super
    在Foundation框架中,super是找不到的剩檀,該關(guān)鍵字應(yīng)該是比self更為奇特的東西憋沿。雖然找不到super,但我們可以看到結(jié)構(gòu)體objc_super沪猴,在官方解釋中我們能看到一些端倪辐啄。

objc_super: The compiler generates an objc_super data structure when it encounters the super keyword as the receiver of a message. It specifies the class definition of the particular superclass that should be messaged.

大致意思就是,當(dāng)遇到super關(guān)鍵字時(shí)运嗜,編譯器會(huì)生成一個(gè)objc_super結(jié)構(gòu)體壶辜,作為消息的接收者,objc_super結(jié)構(gòu)體使得接收消息的父類的定義被明確化担租。
所以砸民,super的含義應(yīng)該是一種編譯指令,它的作用用來(lái)給父類發(fā)送消息,并返回消息響應(yīng)的結(jié)果岭参。

#include <objc/objc.h>
#include <objc/runtime.h>

#pragma GCC system_header

#ifndef OBJC_SUPER
#define OBJC_SUPER

/// Specifies the superclass of an instance. 
struct objc_super {
    /// Specifies an instance of a class.
    __unsafe_unretained id receiver;
    /// Specifies the particular superclass of the instance to message. 
#if !defined(__cplusplus)  &&  !__OBJC2__
    __unsafe_unretained Class class;
#else
    __unsafe_unretained Class super_class;
#endif
};

知悉了這兩點(diǎn)反惕,上面的兩個(gè)問(wèn)題也就迎刃而解了。

解答:

問(wèn)題一:self = [super init]是面向?qū)ο笏枷氲囊环N體現(xiàn)演侯,意義就是姿染,利用父類的init方法為子類初始化父類的公有屬性。
問(wèn)題二:理解這個(gè)先要明確alloc和init的區(qū)別秒际,alloc為對(duì)象開辟內(nèi)存悬赏,init是對(duì)象初始化,所以娄徊,[super init] 是初始化在子類上的舷嗡,super發(fā)出消息的主體對(duì)象是子類,和self是同一個(gè)對(duì)象嵌莉。 class方法和self類似是NSObject協(xié)議中的代理方法,我認(rèn)為class的功能捻脖,OC也已經(jīng)幫我們實(shí)現(xiàn)在每個(gè)子類中锐峭,只是我們看不到而已,所以不管是super還是self發(fā)出的class消息可婶,執(zhí)行的時(shí)候沿癞,都在子類中,返回的都是子類矛渴。

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末椎扬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子具温,更是在濱河造成了極大的恐慌蚕涤,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铣猩,死亡現(xiàn)場(chǎng)離奇詭異揖铜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)达皿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門天吓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人峦椰,你說(shuō)我怎么就攤上這事龄寞。” “怎么了汤功?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵物邑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拂封,這世上最難降的妖魔是什么茬射? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮冒签,結(jié)果婚禮上在抛,老公的妹妹穿的比我還像新娘。我一直安慰自己萧恕,他們只是感情好刚梭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著票唆,像睡著了一般朴读。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上走趋,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天衅金,我揣著相機(jī)與錄音,去河邊找鬼簿煌。 笑死氮唯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的姨伟。 我是一名探鬼主播惩琉,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼夺荒!你這毒婦竟也來(lái)了瞒渠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤技扼,失蹤者是張志新(化名)和其女友劉穎伍玖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剿吻,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡私沮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了和橙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仔燕。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讼昆,死狀恐怖副瀑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情眯牧,我是刑警寧澤办斑,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布外恕,位于F島的核電站杆逗,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鳞疲。R本人自食惡果不足惜罪郊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望尚洽。 院中可真熱鬧悔橄,春花似錦、人聲如沸腺毫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)潮酒。三九已至睛挚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間急黎,已是汗流浹背扎狱。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勃教,地道東北人淤击。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像荣回,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子戈咳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉心软,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,690評(píng)論 0 9
  • 我們常常會(huì)聽說(shuō) Objective-C 是一門動(dòng)態(tài)語(yǔ)言,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢著蛙?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,182評(píng)論 0 7
  • 原文出處:南峰子的技術(shù)博客 Objective-C語(yǔ)言是一門動(dòng)態(tài)語(yǔ)言删铃,它將很多靜態(tài)語(yǔ)言在編譯和鏈接時(shí)期做的事放到了...
    _燴面_閱讀 1,222評(píng)論 1 5
  • 新雨茫漓落驚春,又洗飛花月燭塵踏堡。 清風(fēng)不許夜燈火猎唁,且過(guò)蓬門吹舊人。 芳華最是有情處顷蟆,蕭然久逝香無(wú)痕诫隅。 長(zhǎng)歌猶在陽(yáng)城...
    不知世間何事閱讀 339評(píng)論 0 1
  • 2.早晨六點(diǎn)起來(lái),給家里人煎了土豆餅帐偎,并讓弟媳婦帶到單位吃逐纬,她會(huì)倍感溫暖吧! 3.中午包餃子削樊,給媽媽熬中藥泡腳豁生,每...
    竹林千頃田華閱讀 167評(píng)論 0 0