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]);
输出 参考
编码 |
含义 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C++标准的 |
|
|
|
字符串( |
|
对象(无论是静态指定的还是通过 |
|
类( |
|
方法选标( |
[array type] |
数组 |
{name=type...} |
结构体 |
(name=type...) |
联合体 |
|
num个bit的位域 |
|
type类型的指针 |
|
未知类型(其它时候,一般用来指函数指针) |
当 [invocation invoke];是调用SEL。上述第二个参数为自身。-(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]; } }
- (void)encodeWithCoder:(NSCoder *)encoder{
NSDictionary *attrDic = [self getKeyAndObjectForDictionry];
if (attrDic == nil) {
return;
}
NSEnumerator *keyEnum = [attrDic keyEnumerator];
id attributeName;
while ((attributeName = [keyEnum nextObject])) {
SEL getSel = NSSelectorFromString(attributeName);
if ([self respondsToSelector:getSel]) {
NSMethodSignature *signature = nil;
signature = [self methodSignatureForSelector:getSel];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self];
[invocation setSelector:getSel];
NSObject *valueObj = nil;
[invocation invoke];
[invocation getReturnValue:&valueObj];
if (valueObj) {
[encoder encodeObject:valueObj forKey:attributeName];
}
}
}
}