我们在实际开发中须要对离散的方式加锁实现线程安全,当然我们有多种实现方式,这仅仅是当中一种,使用起来比較方便
+ (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;
}
}