一个object的分类,可以在调用performSelector:函数的时候不限制传参的数量(BOOL需要封装一层).
//为了让performSelector:后面带入的参数可识别,很有必要将bool封装一层,用于在后面解析函数时候的识别
@interface BoolClass:NSObject
@property (nonatomic,assign)BOOL b_;
+(BoolClass *)getBoolClass:(BOOL)b2_;
@end
#define BOOLCLASS(b) [BoolClass getBoolClass:b]
@interface NSObject (Extension)
//远端调用的时候可扩展,不受两个参数的限制
- (id)performSelector:(SEL)aSelector withObjects:(void*)object1,... NS_REQUIRES_NIL_TERMINATION;
@end
.m文件开始
@implementation BoolClass
+(BoolClass *)getBoolClass:(BOOL)b2_
{
BoolClass *bc=[BoolClass new];
bc.b_=b2_;
return bc.autorelease;
}
@end
@implementation NSObject (Extension)
- (id)performSelector:(SEL)aSelector withObjects:(void*)object,... NS_REQUIRES_NIL_TERMINATION
{
va_list args;
va_start(args, object);
NSInteger index=2;//0 是本身,1 是SEL
NSMethodSignature *sig=[self.class instanceMethodSignatureForSelector:aSelector];
NSInvocation *invo=[NSInvocation invocationWithMethodSignature:sig];
[invo setTarget:self];
[invo setSelector:aSelector];
for(id isId=object;isId!=nil;isId=va_arg(args, id),index++)
{
if([isId isKindOfClass:BoolClass.class])
{
BOOL b_=((BoolClass *)isId).b_;
[invo setArgument:&b_ atIndex:index];
continue;
}
[invo setArgument:&isId atIndex:index];
}
va_end(args);
[invo retainArguments];
[invo invoke];
//返回函数调用后的返回值
const char *returnType=sig.methodReturnType;
id returnValue;
if(!strcasecmp(returnType, @encode(void)))//没有返回值
{
returnValue=nil;
}else if(!strcasecmp(returnType, @encode(id))){//返回值为对象
[invo getReturnValue:&returnValue];
}else{//返回值为NSInteger Bool
void *buffer=(void *)malloc([sig methodReturnLength]);
[invo getReturnValue:buffer];
if(!strcasecmp(returnType, @encode(BOOL)))
returnValue=[NSNumber numberWithBool:*((BOOL *)buffer)];
else if(!strcasecmp(returnType, @encode(NSInteger)))
returnValue=[NSNumber numberWithBool:*((NSInteger *)buffer)];
else
returnValue=[NSNumber numberWithBool:buffer];
}
return returnValue;
}
@end
//最后推荐一下念茜大神的博客: http://blog.csdn.net/yiyaaixuexi