一個NSMethodSignature對象記錄著某個方法的返回值類型信息以及參數類型信息。它用于轉發消息接收者無法響應的消息。
可以通過methodSignatureForSelector:獲取類方法或實例方法的簽名;也可以用instanceMethodSignatureForSelector:獲取實例方法的簽名;
舉個例子:
另外,發現:
只要返回值和參數類型都相同,那么不論方法名是否相同,都會返回同一個方法簽名對象。
打印signature1對象:
根據打印,可知- (void)test:(NSString *)string的方法簽名中包含了四種信息:
return value對應的type encoding為v
argument 0對應的type encoding為@
argument 1對應的type encoding為:
argument 2對應的type encoding為@
至于type encoding(類型編碼)是什么,后面會講到。
以上兩個獲取方法簽名的方法都是從根類NSObject中繼承而來的。還有一種手動創建方法簽名的方式,如下:
即signatureWithObjeCTypes:,它是NSMethodSignature的類方法,參數為字符常量,那么這個參數傳入的就是由上面打印的四種信息而組成。
然后創建好的NSMethodSignature對象會被用來創建NSInvocation對象,這個NSInvocation對象呢,就是作為消息轉發中的最后一步:- (void)forwardInvocation:(NSInvocation *)anInvocation中的參數的。
默認情況下,如果一個對象無法響應某個消息,那么,調用NSObject的doesNotRecognizeSelector方法拋出異常。
有了消息轉發機制,NSInvocation對象會利用NSMethodSignature對象中的信息,將消息進行封裝,然后調用forwardInvocation方法將消息轉發給消息的真正接收者。
Type Encoding
NSMethodSignature對象是根據字符串創建的,這里的字符串代表了某個方法的返回值類型以及參數類型的字符串編碼。你可以使用編譯器命令:encode()來獲取特定類型的字符串編碼。
一個方法簽名包含代表方法返回值的一個或多個字符,后面跟上隱式參數self以及_cmd的字符串編碼,然后后面再跟上零個或多個明確的參數的字符編碼。可以通過methodReturnType屬性獲取返回值類型的字符編碼,可以通過methodReturnLength屬性獲取返回值類型的長度。
例如:NSString的實例方法containsString:的方法簽名包含以下參數:
1.返回值:BOOL類型, @encode(BOOL) ——c
2.方法接收者(self):id類型,@encode(id)——@
3.方法名(_cmd):SEL,@encode(SEL)——:
4.方法參數:NSString類型,@encode(NSString *)——@