一個(gè)NSMethodSignature對(duì)象記錄著某個(gè)方法的返回值類(lèi)型信息以及參數(shù)類(lèi)型信息。它用于轉(zhuǎn)發(fā)消息接收者無(wú)法響應(yīng)的消息卖哎。
可以通過(guò)methodSignatureForSelector:獲取類(lèi)方法或?qū)嵗椒ǖ暮灻灰部梢杂胕nstanceMethodSignatureForSelector:獲取實(shí)例方法的簽名瑞筐;
舉個(gè)例子:
另外何缓,發(fā)現(xiàn):
只要返回值和參數(shù)類(lèi)型都相同,那么不論方法名是否相同蕴坪,都會(huì)返回同一個(gè)方法簽名對(duì)象肴掷。
打印signature1對(duì)象:
根據(jù)打印,可知- (void)test:(NSString *)string的方法簽名中包含了四種信息:
return value對(duì)應(yīng)的type encoding為v
argument 0對(duì)應(yīng)的type encoding為@
argument 1對(duì)應(yīng)的type encoding為:
argument 2對(duì)應(yīng)的type encoding為@
至于type encoding(類(lèi)型編碼)是什么背传,后面會(huì)講到呆瞻。
以上兩個(gè)獲取方法簽名的方法都是從根類(lèi)NSObject中繼承而來(lái)的。還有一種手動(dòng)創(chuàng)建方法簽名的方式径玖,如下:
即signatureWithObjeCTypes:痴脾,它是NSMethodSignature的類(lèi)方法,參數(shù)為字符常量梳星,那么這個(gè)參數(shù)傳入的就是由上面打印的四種信息而組成赞赖。
然后創(chuàng)建好的NSMethodSignature對(duì)象會(huì)被用來(lái)創(chuàng)建NSInvocation對(duì)象,這個(gè)NSInvocation對(duì)象呢冤灾,就是作為消息轉(zhuǎn)發(fā)中的最后一步:- (void)forwardInvocation:(NSInvocation *)anInvocation中的參數(shù)的前域。
默認(rèn)情況下,如果一個(gè)對(duì)象無(wú)法響應(yīng)某個(gè)消息韵吨,那么话侄,調(diào)用NSObject的doesNotRecognizeSelector方法拋出異常。
有了消息轉(zhuǎn)發(fā)機(jī)制学赛,NSInvocation對(duì)象會(huì)利用NSMethodSignature對(duì)象中的信息年堆,將消息進(jìn)行封裝,然后調(diào)用forwardInvocation方法將消息轉(zhuǎn)發(fā)給消息的真正接收者盏浇。
Type Encoding
NSMethodSignature對(duì)象是根據(jù)字符串創(chuàng)建的变丧,這里的字符串代表了某個(gè)方法的返回值類(lèi)型以及參數(shù)類(lèi)型的字符串編碼。你可以使用編譯器命令:encode()來(lái)獲取特定類(lèi)型的字符串編碼绢掰。
一個(gè)方法簽名包含代表方法返回值的一個(gè)或多個(gè)字符痒蓬,后面跟上隱式參數(shù)self以及_cmd的字符串編碼,然后后面再跟上零個(gè)或多個(gè)明確的參數(shù)的字符編碼滴劲」ド梗可以通過(guò)methodReturnType屬性獲取返回值類(lèi)型的字符編碼,可以通過(guò)methodReturnLength屬性獲取返回值類(lèi)型的長(zhǎng)度班挖。
例如:NSString的實(shí)例方法containsString:的方法簽名包含以下參數(shù):
1.返回值:BOOL類(lèi)型鲁捏, @encode(BOOL) ——c
2.方法接收者(self):id類(lèi)型,@encode(id)——@
3.方法名(_cmd):SEL萧芙,@encode(SEL)——:
4.方法參數(shù):NSString類(lèi)型给梅,@encode(NSString *)——@