iOS中的 v@:@

Objective-C中的方法默認被隱藏了兩個參數:self和_cmd。self指向對象本身,_cmd指向方法本身。舉兩個例子來說明:

    例一:- (NSString *)name

這個方法實際上有兩個參數:self和_cmd。

    例二:- (void)setValue:(int)val

這個方法實際上有三個參數:self, _cmd和val。

    被指定爲動態實現的方法的參數類型有如下的要求:

   A.第一個參數類型必須是id(就是self的類型)

   B.第二個參數類型必須是SEL(就是_cmd的類型)

   C.從第三個參數起,可以按照原方法的參數類型定義。舉兩個例子來說明:

    例一:setHeight:(CGFloat)height中的參數height是浮點型的,所以第三個參數類型就是f。

    例二:再比如setName:(NSString *)name中的參數name是字符串類型的,所以第三個參數類型就是@

    這裏v@:@是什麼東西呢?實際上,這裏的第一個字符v代表函數的返回類型是void,後面三個字符參考上面2)中的解釋就可以知道,分別是self, _cmd, name這三個參數的類型id, SEL, NSString。

   接着程序進入forwardInvocation方法。得到的key爲方法名稱setName:,然後利用[invocation getArgument:&obj atIndex:2]; 獲取到參數值,這裏是“c++ primer”。這裏的index爲什麼要取2呢?如前面分析,第0個參數是self,第1個參數是_cmd,第2個參數纔是方法後面帶的那個參數。

   最後利用一個可變字典來賦值。這樣就完成了整個setter過程。 

4)在main.m中有一句代碼是 NSLog(@"%@", book.name);,程序運行到這裏時,會去Book.m中尋找name這個取值方法 。但是Book.m裏並沒有這個取值方法,於是程序進入methodSignatureForSelector:中進行消息轉發。執行完之後,以"@@:"作爲方法簽名類型返回。這裏第一字符@代表函數返回類型NSString,第二個字符@代表self的類型id,第三個字符:代表_cmd的類型SEL。

   接着程序進入forwardInvocation方法。得到的key爲方法名稱name。最後根據這個key從字典裏獲取相應的值,這樣就完成了整個getter過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章