您的位置:首页 > 其它

利用NSInvocation对方法进行抽象,实现对方法的加锁

2016-03-16 15:14 495 查看
我们在实际开发中须要对离散的方式加锁实现线程安全,当然我们有多种实现方式,这仅仅是当中一种,使用起来比較方便

+ (id)performSelectorWithTarget:(id)target selector:(SEL)selector withObject:(id)arg1
,...NS_REQUIRES_NIL_TERMINATION;

{

@synchronized(self){

id result =
nil;

NSMethodSignature *sig = [target
methodSignatureForSelector:selector];

if (!sig)
return result;

NSInvocation* myInvocation = [NSInvocation
invocationWithMethodSignature:sig];

[myInvocation setTarget:target];

[myInvocation setSelector:selector];

int argumentStart =
2;

va_list args;

va_start(args, arg1);
// scan for arguments after firstObject.

// get rest of the objects until nil is found

for (id obj = arg1; obj !=
nil; obj = va_arg(args,id)) {

[myInvocation setArgument:&obj
atIndex:argumentStart];

argumentStart++;

}

va_end(args);

[myInvocation retainArguments];

[myInvocation invoke];

//获得返回值类型

const
char *returnType = sig.methodReturnType;

//声明返回值变量

//假设没有返回值,也就是消息声明为void,那么returnValue=nil

if( !strcmp(returnType,
@encode(void)) ){

result = nil;

}

//假设返回值为对象。那么为变量赋值

else
if( !strcmp(returnType,
@encode(id)) ){

[myInvocation getReturnValue: &result];

}else{

//假设返回值为普通类型NSInteger BOOL

//返回值长度

NSUInteger length = [sig
methodReturnLength];

//依据长度申请内存

void *buffer = (void *)malloc(length);

//为变量赋值

[myInvocation getReturnValue:buffer];

if( !strcmp(returnType,
@encode(BOOL)) ) {

result = [NSNumber
numberWithBool:*((BOOL*)buffer)];

}

else
if( !strcmp(returnType,
@encode(NSInteger)) ){

result = [NSNumber
numberWithInteger:*((NSInteger*)buffer)];

}else {

result = [NSValue
valueWithBytes:buffer objCType:returnType];

}

free(buffer);

}

return result;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: