利用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;
}
}
+ (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;
}
}
相关文章推荐
- 复利计算的总结
- error: stray '\343' in program 问题解决
- HTTP和HTTPS详解
- 持久化操作(写入文件)
- error: stray '\343' in program 问题解决
- 数组内元素的排序
- Red Hat Linux 7.2配置本地yum源
- Android WebView属性及用法
- 2016.3.15Android 学习汇总
- 堵塞队列--BlockingQueue
- Android异步消息处理机制
- Hello World
- 学会享受孤独是通往成功的第一步
- 了解负载均衡 会话保持 session同步(转)
- 通过ObjectOutputStream序列化和使用ObjectInputStream反序列化
- RatingBar自定义背景下面有直线
- kmp算法及其c++实现
- js兼容性之css的float
- C++继承20160214
- 自信来源于什么?