類方法中使用self注意事項,類方法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 delegateTabBarController————使用[TabBarController sharedInstance]————(lldb) po delegate<TabBarController: 0x18952020>
很明顯:使用self,實際上是Class類型,並不是我們期望的類對象。所以,在RequestItem裡面判斷response selector的時候就沒有判斷出來。
針對第二種情境:在類(執行個體)方法中使用self調用方法1. 執行個體方法中,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。