使用NSMethodSignature和NSInvocation实现消息转发

来源:互联网 发布:java request过去路径 编辑:程序博客网 时间:2024/05/17 03:04
NSInvocation类的实例用于封装Objective-C消息。一个调用对象中含有一个目标对象、一个方法选择器、以及方法参数。您可以动态地改变调用对象中消息的目标及其参数,一旦消息被执行,您就可以从该对象得到返回值。通过一个调用对象可以多次调用目标或参数不同的消息。

创建NSInvocation对象需要使用NSMethodSignature对象,该对象负责封装与方法参数和返回值有关系的信息。NSMethodSignature对象的创建又需要用到一个方法选择器。NSInvocation的实现还用到Objective-C运行环境的一些函数。

使用和限制

NSInvocation对象是分布式、撤消管理、消息传递、和定时器对象编程接口的一部分。在需要去除消息发送对象和接收对象之间的耦合关系的类似场合下,您也可以使用。


NSMethodSignature顾名思义应该就是“方法签名”,类似于C++中的编译器时的函数签名。

官方定义该类为对方法的参数、返回类似进行封装,协同NSInvocation实现消息转发。
通过消息转发可以用B实现A的方法。也是一种多重继承的解决方法。

interface LOCBird : NSObject { NSString* name_; }@end@implementation LOCBird- (id)init{ self = [super init]; if (self) { name_ = [[NSString alloc] initWithString:@"I am a Bird!!"]; } return self;}- (void)dealloc{ [name_ release]; [super dealloc];}- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ NSMethodSignature* signature = [super methodSignatureForSelector:aSelector]; if (signature==nil) { signature = [name_ methodSignatureForSelector:aSelector]; } NSUInteger argCount = [signature numberOfArguments]; for (NSInteger i=0 ; i<argCount ; i++) { NSLog(@"%s" , [signature getArgumentTypeAtIndex:i]); } NSLog(@"returnType:%s ,returnLen:%d" , [signature methodReturnType] , [signature methodReturnLength]); NSLog(@"signature:%@" , signature); return signature;}- (void)forwardInvocation:(NSInvocation *)anInvocation{ NSLog(@"forwardInvocation:%@" , anInvocation); SEL seletor = [anInvocation selector]; if ([name_ respondsToSelector:seletor]) { [anInvocation invokeWithTarget:name_]; } }@end

//调用

id bird = [[LOCBird alloc] init]; NSLog(@"len= %d", [bird length]);

使用方法

-(void) initWithTarget:(id) rec selector:(SEL) cb{ anchorPoint_ = ccp(0.5f, 0.5f); NSMethodSignature * sig = nil; if( rec && cb ) { sig = [rec methodSignatureForSelector:cb]; invocation = nil; invocation = [NSInvocation invocationWithMethodSignature:sig]; [invocation setTarget:rec]; [invocation setSelector:cb]; [invocation setArgument:&self atIndex:2]; [invocation retain]; }}

[invocation invoke];是调用SEL。上述第二个参数为自身。



0 0