iOS self 和 super區(qū)別以及為什么要self = [super init];

//聯(lián)系人:石虎QQ: 1224614774昵稱:嗡嘛呢叭咪哄

一、self和super區(qū)別

區(qū)別:

- self調(diào)用自己方法,super調(diào)用父類方法

- self是類,super是預(yù)編譯指令

- self class】和【super class】輸出是一樣的

self和super底層實(shí)現(xiàn)原理:

-當(dāng)使用self調(diào)用方法時(shí),會(huì)從當(dāng)前類的方法列表中開始找,如果沒(méi)有,就從父類中再找;而當(dāng)使用super時(shí),則從父類的方法列表中開始找,然后調(diào)用父類的這個(gè)方法。

-當(dāng)使用self調(diào)用時(shí),會(huì)使用objc_msgSend函數(shù):id objc_msgSend(id theReceiver,SEL theSelector,...)。第一個(gè)參數(shù)是消息接收者,第二個(gè)參數(shù)是調(diào)用的具體類方法的selector,后面是selector方法的可變參數(shù)。以[self setName:]為例,編譯器會(huì)替換成調(diào)用objc_msgSend的函數(shù)調(diào)用,其中theReceiver是self,theSelector是@selector(setName:),這個(gè)selector是從當(dāng)前self的class的方法列表開始找的setName,當(dāng)找到后把對(duì)應(yīng)的selector傳遞過(guò)去。

-當(dāng)使用super調(diào)用時(shí),會(huì)使用objc_msgSendSuper函數(shù):id objc_msgSendSuper(struct objc_super *super,SEL op,...)第一個(gè)參數(shù)是個(gè)objc_super的結(jié)構(gòu)體,第二個(gè)參數(shù)還是類似上面的類方法的selector,

二、為什么要self =[super init];

符合oc繼承類初始化規(guī)范super同樣也是這樣,[super init]去self的super中調(diào)用init super調(diào)用superSuper的init。直到根類NSObject中的init,根類中init負(fù)責(zé)初始化內(nèi)存區(qū)域向里面添加一些必要的屬性,返回內(nèi)存指針,這樣延著繼承鏈初始化的內(nèi)存指針被從上到下傳遞,在不同的子類中向塊內(nèi)存添加子類必要的屬性,直到我們的A類中得到內(nèi)存指針,賦值給slef參數(shù),在if(slef){//添加A的屬性}

下面來(lái)看看這個(gè):

@implementation Son : Father

-(id)init

{

self =[super init];

if(self)

{

NSLog(@"%@",NSStringFromClass([self class]));

NSLog(@"%@",NSStringFromClass([super class]));

}

return self;

}

@end

應(yīng)該不難分析出打印結(jié)果:

Son

Son

當(dāng)發(fā)送class消息時(shí)不管是self還是super其消息主體依然是self,也就是說(shuō)self和super指向的是同一個(gè)對(duì)象。只是查找方法的位置區(qū)別,一個(gè)從本類,一個(gè)從本類的超類。

一般情況下class方法只有在根類NSObject中定義,極少情況有子類重寫class方法,

所以[slef class]和[super class]都是在根類中找方法實(shí)現(xiàn),消息接收主體又都是a

如果重寫可能會(huì)不一樣。

自然都打印出Son

在來(lái)一個(gè)例子:

#import

@interface EngineSuper : NSObject

-(void)printCurrentClass;

@end

#import "EngineSuper.h"

@implementation EngineSuper

-(void)printCurrentClass{

NSLog(@"=EngineSuper=======%@",[self class]);

}

@end

@interface Engine : EngineSuper

-(void)printSupClass;

@end

@implementation Engine

-(void)printSupClass{

[super printCurrentClass];

}

//調(diào)用:

Engine *engine =[[Engine alloc]init];

[engine? printCurrentClass];//直接調(diào)用父類方法,engine沒(méi)重載它

[engine? printSupClass];//間接調(diào)用父類方法,

打印當(dāng)然都是:

Engine

Engine

方法體中self始終指代方法的接收者及對(duì)象engine。,

換成NSLog(@”=EngineSuper=======%@”,[super class]);結(jié)果也是一樣的。

super就是個(gè)障眼法發(fā),編譯器符號(hào),它可以替換成[slef class],只不過(guò)方法是從self的超類開始尋找。

謝謝!!!

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

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,030評(píng)論 0 9
  • 依舊是夢(mèng)里的故事。 很簡(jiǎn)單的一個(gè)夢(mèng),我卻反復(fù)回想了很多次。夢(mèng)里幾次哭出來(lái)。莫名地倍覺委屈和孤獨(dú)。 在夢(mèng)里,我有一對(duì)...
    慕顏未央閱讀 650評(píng)論 3 3
  • 女人好比梨,外甜內(nèi)酸,吃梨的人不知道梨的心是酸的,因?yàn)槌缘阶詈缶桶研娜恿?,所以男人從?lái)不懂女人的心。 男人就好比洋...
    黃桃罐頭寶寶閱讀 986評(píng)論 0 1

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