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]);
输出 参考
表 6-1 Objective-C类型编码
编码
含义
c
char
i
int
s
short
l
long
在64位程序中,l为32位。
q
long long
C
unsigned char
I
unsigned int
S
unsigned short
L
unsigned long
Q
unsigned long long
f
float
d
double
B
C++标准的bool
或者C99标准的_Bool
v
void
*
字符串(char *
)
@
对象(无论是静态指定的还是通过id
引用的)
#
类(Class
)
:
方法选标(SEL)
[array type]
数组
{name=type...}
结构体
(name=type...)
联合体
b
num
num个bit的位域
^
type
type类型的指针
?
未知类型(其它时候,一般用来指函数指针)
使用方法
-(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。上述第二个参数为自身。
用
NSMethodSignature和
NSInvocation实现编码
- (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];
}
}
}
}