0x01 self
當調用對象方法時,編譯器都會默認傳入一個指向本對象的指針,所以不同的對象都會調用到正確的成員變量。
這個指針就是self,它的值就是new時在堆中分配內存的首地址。
用在方法中時,哪個對象調用該方法self指針就指向哪個對象,可以把它當作調用該方法的那個對象的指針一樣使用。
Whenever you’re writing a method implementation, you have access to an important hidden value, self. Conceptually, self is a way to refer to “the object that’s received this message.” It’s apointer, just like the greeting value above, and can be used to call a method on the current receiving object.
- 誰調用了當前方法,self就代表誰:self出現在對象方法中,self就代表對象;self出現在類方法中,self就代表類;
- 在對象方法中利用"self.成員變量名"可以訪問當前對象內部的成員變量;
- [self 方法名]可以調用對象的方法/類方法。
0x02 super
self是一個隱藏參數變量,指向當前調用方法的對象,而super並不是隱藏參數,只是編譯器的指令符號。
使用self調用方法時,self先從當前類中尋找方法,如果沒有尋找到再去父類中尋找。
而super直接在父類中尋找方法。
There’s anotherimportant keyword available to you in Objective-C, called super. Sending a message to super is a way to call through to a method implementation defined by a superclass further up the inheritance chain. The most common use of super is when overriding a method.
最終都會搜索完整個繼承鏈。所以, [self class]和[super class]輸出是一樣的。
0x03 self和super的配合使用
self = [super init] 是再熟悉不過的一行代碼了,簡單的一行代碼足以看出self和super 的關鍵作用。
Objective-C的繼承特性,使子類繼承父類時能夠獲得相關的屬性和方法。
所以在子類的初始化方法中,必須首先調用父類的初始化方法,完成父類相關資源的初始化。
[super init]去self的super中調用init:方法, 然後super會調用其父類的init:方法,以此類推,直到找到根類NSObject中的init:方法。然後根類中的init:方法負責初始化內存區域,添加一些必要的屬性,返回內存指針,沿着繼承鏈指針從上到下進行傳遞,同時在不同的子類中可以向內存添加必要的屬性。最後到達當前類中,把內存地址賦值給self參數。
如果調用[super init]失敗的話,將通過判斷self來決定是否執行子類的初始化操作。