self和super區(qū)別
self
是關(guān)鍵字
代表當(dāng)前方法的調(diào)用者
如果是類(lèi)方法:代表當(dāng)前類(lèi)
如果是對(duì)象方法:代表當(dāng)前類(lèi)的對(duì)象
super
編譯器指令
[self message]和[super message]的實(shí)現(xiàn)
其實(shí)不管是self還是super真正調(diào)用的對(duì)象都是一樣的,只是查找方法的位置不一樣,self是從當(dāng)前類(lèi)結(jié)構(gòu)中開(kāi)始查找,super是從父類(lèi)中查找,但方法真正的接受者都是當(dāng)前類(lèi)或者當(dāng)前類(lèi)的對(duì)象
[self message]:
會(huì)轉(zhuǎn)化為objc_msgSend(id self,SEL _cmd)這個(gè)函數(shù),在當(dāng)前類(lèi)結(jié)構(gòu)中找到方法并且調(diào)用
[super message]
會(huì)轉(zhuǎn)化為id objc_msgSendSuper(struct __rw_objc_super *super, SEL op, …)
,對(duì)比[self message]這里除了函數(shù)名加了super以外,第一個(gè)參數(shù)由self變成了一個(gè)結(jié)構(gòu)體,下面讓我們來(lái)解開(kāi)這個(gè)結(jié)構(gòu)體的真面目
struct __rw_objc_super {
struct objc_object *object; //代表當(dāng)前類(lèi)的對(duì)象
struct objc_object *superClass;
__rw_objc_super(struct objc_object *o, struct objc_object *s) : object(o), superClass(s) {}
};
這個(gè)結(jié)構(gòu)體中有兩個(gè)參數(shù):object的對(duì)象和一個(gè)superClass的結(jié)構(gòu)體指針,這里的object相當(dāng)于上面的self
在執(zhí)行[super message]時(shí),會(huì)做下面的事
- 編譯器會(huì)先構(gòu)造一個(gè)__rw_objc_super的結(jié)構(gòu)體
- 然后去superClass的方法列表中找方法
- 找到之后由object調(diào)用。
所以當(dāng)你用[self Class]和[super Class]打印類(lèi)的時(shí)候,打印的都是同一個(gè)類(lèi),因?yàn)樗麄冎皇遣檎曳椒ǖ奈恢貌煌?,但是調(diào)用方法的類(lèi)/對(duì)象是一樣的.
為什要寫(xiě)self = [super init]?
因?yàn)樵赬code中,你輸入init然后tab就會(huì)幫你補(bǔ)全這個(gè)方法,以至于我一直都忽略了為什么在[super init]之后還要賦值給self,然后進(jìn)行判斷,其實(shí)這和類(lèi)簇有關(guān)系,我們不能保證init的內(nèi)存和alloc出來(lái)的內(nèi)存是同一塊內(nèi)存,像NSString在alloc和init之后的對(duì)象分別是NSPlaceholderString和__NSCFConstantString*造成[super init]之后的內(nèi)存被改變,所以在[super init]之后是nil,因此我們不能保證alloc和init的是同一塊內(nèi)存,加上這樣的判斷是為了提高容錯(cuò)性,如果init成功就返回對(duì)象,否則返回nil.
原文鏈接:https://blog.csdn.net/li15809284891/article/details/54836905