Objective-C類方法中使用self注意事項
類方法中使用self會是什麼結果,下午在編碼中遇到這個問題:“在類方法中直接使用了self,導致函式沒有被呼叫。”然後,順便研究了一下,在類(或例項)方法中self是如何表現的。
第一、在類方法中使用self作為引數,需要特別注意。第二、在類(或例項)方法中使用self呼叫方法(如果是錯誤的使用,編譯器會給出編譯錯誤)。
第一種情況:在類方法中使用self作為引數
一般來說:當引數指定型別,程式設計師傳入的self也是對應型別。但是,編譯器給出警告。編譯器提示開發者:把Class當做TabBarController使用了
另外一種情況:如果引數是id型別,那麼編譯器不報錯。如下程式碼:+ (void)goToInfoPage{ RequestItem *requestItem = [[RequestItem alloc] initWithOwner:[TabBarController sharedInstance]];/*使用self可以編譯,但達不到預期效果*/ [requestItem setDelegateTarget:[TabBarController sharedController] /*使用self可以編譯,但達不到預期效果*/ succeedMethod:@selector(requestInfoSuccess:) failedMethod:@selector(requestInfoFailure:)]; }
其中 initWithOwner和setDelegateTarget的引數都是id型別,上面的程式碼使用self可以通過編譯,但在request後,requestInfoSuccess和requestInfoFailure一個都沒有被執行。在initWithOwner函式中列印引數的值如下:
————使用self————
(lldb) po delegate
TabBarController
————使用[TabBarController sharedInstance]————
(lldb) po delegate
<TabBarController: 0x18952020>
很明顯:使用self,實際上是Class型別,並不是我們期望的類物件。所以,在RequestItem裡面判斷response selector的時候就沒有判斷出來。
針對第二種場景:在類(例項)方法中使用self呼叫方法
2. 例項方法中,self【不可以】呼叫類方法,此時self不是Class。【編譯錯誤】No visible @interface for 'xx' declares the selector ‘xx’
3. 類方法中,self【可以】呼叫類方法,此時self是Class
4. 類方法中,self【不可以】呼叫例項方法。【編譯錯誤】 No known class method for selector ‘xxxxx’
self跟著函式的本質不同,也會不同。所以,在類方法中使用self,就要特別注意了。
【總結】:
1,例項方法裡面的self,是物件的首地址。2,類方法裡面的self,是Class。類方法不可以使用例項變數,但可以使用self,因為self不是例項變數。此時.self是Class
儘管在同一個類裡面的使用self,但是self卻有著不同的解讀。在類方法裡面的self,可以翻譯成class self;在例項方法裡面的self,應該被翻譯成為object self。在類方法裡面的self和例項方法裡面的self有著本質上的不同,儘管他們的名字都叫self。