iOS self&super

self和super區別

self

  1. 是關鍵字

  2. 代表當前方法的調用者

    • 如果是類方法:代表當前類
    • 如果是對象方法:代表當前類的對象

super

編譯器指令

[self message]和[super message]的實現

其實不管是self還是super真正調用的對象都是一樣的,只是查找方法的位置不一樣,self是從當前類結構中開始查找,super是從父類中查找,但方法真正的接受者都是當前類或者當前類的對象
[self message]:

會轉化為objc_msgSend(id self,SEL _cmd)這個函數,在當前類結構中找到方法并且調用

[super message]

會轉化為id objc_msgSendSuper(struct __rw_objc_super *super, SEL op, …)
,對比[self message]這里除了函數名加了super以外,第一個參數由self變成了一個結構體,下面讓我們來解開這個結構體的真面目

struct __rw_objc_super {
struct objc_object *object; //代表當前類的對象
struct objc_object *superClass;
__rw_objc_super(struct objc_object *o, struct objc_object *s) : object(o), superClass(s) {}
};
1
2
3
4
5
這個結構體中有兩個參數:object的對象和一個superClass的結構體指針,這里的object相當于上面的self
在執行[super message]時,會做下面的事

  1. 編譯器會先構造一個__rw_objc_super的結構體
  2. 然后去superClass的方法列表中找方法
  3. 找到之后由object調用。
    所以當你用[self Class]和[super Class]打印類的時候,打印的都是同一個類,因為他們只是查找方法的位置不同,但是調用方法的類/對象是一樣的.

為什要寫self = [super init]?

因為在Xcode中,你輸入init然后tab就會幫你補全這個方法,以至于我一直都忽略了為什么在[super init]之后還要賦值給self,然后進行判斷,其實這和類簇有關系,我們不能保證init的內存和alloc出來的內存是同一塊內存,像NSString在alloc和init之后的對象分別是NSPlaceholderString和__NSCFConstantString*造成[super init]之后的內存被改變,所以在[super init]之后是nil,因此我們不能保證alloc和init的是同一塊內存,加上這樣的判斷是為了提高容錯性,如果init成功就返回對象,否則返回nil.

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容