NSInvocation使一個OC消息轉(zhuǎn)換為一個對象,存儲著要轉(zhuǎn)發(fā)的消息,包含了消息中的target率碾、selector等限、參數(shù)、返回值释漆。參數(shù)可以直接被設(shè)置悲没,在NSInvocation對象被派發(fā)時自動獲取返回值。
只要保證方法的簽名不變灵汪,其target檀训、選擇子、參數(shù)都可以變化享言,可重復(fù)的派發(fā)峻凫。
實(shí)現(xiàn)OC調(diào)用,調(diào)用自定義方法??览露,將消息轉(zhuǎn)發(fā)給 target 的 selector 方法
- (void)invoke:(id)target selector:(SEL)selector arguments:(NSArray *)arguments
{
//生成selector的函數(shù)簽名
//若有另一個selector1與這個selector返回值荧琼、參數(shù)列表相同,也可以用selector1的函數(shù)簽名
NSMethodSignature *signature = [[target class] instanceMethodSignatureForSelector:selector];
//根據(jù)函數(shù)簽名生成一個NSInvocation對象,NSInvocation對象的生成僅能通過其類方法實(shí)現(xiàn)
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
//設(shè)置target命锄、selector堰乔,并且target、selector分別占據(jù)其參數(shù)列表第0個和第1個的位置
[invocation setTarget:target];
[invocation setSelector:method];
NSNumber *num = arguments[0];
NSString *str = arguments[1];
[invocation setArgument:&num atIndex:2];
[invocation setArgument:&str atIndex:3];
//轉(zhuǎn)發(fā)此消息
[invocation invoke];
//獲取其返回值
NSString *returnValue;
[invocation getReturnValue:&returnValue]; //此時脐恩,returnValue就保存著selector的返回值
}
在 NSInvocation 參數(shù)列表中镐侯,其 target、selector 分別占據(jù)了第0個和第1個位置驶冒,所以實(shí)際的參數(shù)從2開始往后寫苟翻,所以其參數(shù)列表還可以這么寫:
[invocation setArgument:&target atIndex:0];
[invocation setArgument:&selector atIndex:1];
target 中 selector 方法??,必須滿足NSInvocation中所設(shè)置的骗污,兩個參數(shù):第一個 NSNumber 類型崇猫,第二個為 NSString 類型,并且有函數(shù)返回值需忿。
- (NSString *)hello:(NSNumber *)num arg1:(NSString *)arg1
{
NSLog(@"hello");
NSLog(@"num:%d",num.intValue);
NSLog(@"arg1:%@",arg1);
return @"123";
}
由于NSInvocation不會默認(rèn)保留其參數(shù)诅炉,在創(chuàng)建NSInvocation類和使用它時,其參數(shù)可能被銷毀了屋厘,這就需要顯示的保留這些參數(shù)涕烧。
- (void)retainArguments;