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

简介:

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


+ (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( !strc


mp(returnType, @encode(NSInteger)) ){

                

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

            }else {

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

            }

            

            free(buffer);

        }

        return result;

    }

}





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5283683.html,如需转载请自行联系原作者

目录
打赏
0
0
0
0
56
分享
相关文章
架构系列——通过ReentrantLock源码分析给对象上锁的原理
架构系列——通过ReentrantLock源码分析给对象上锁的原理
Lock锁和AQS之间的关系与区别:基于第一原理的深入分析
【11月更文挑战第26天】在Java并发编程中,锁(Lock)和队列同步器(AbstractQueuedSynchronizer,简称AQS)是两个核心概念。它们为多线程环境下的同步和互斥提供了强大的支持。本文将从第一原理出发,深入探讨Lock锁和AQS之间的关系与区别,同时分析它们的相关概念、业务场景、历史背景、功能点以及底层原理,并使用Java代码进行模拟实现。
31 1
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
99 1
除了双重检查锁定机制外的线程安全单例模式
除了双重检查锁定机制外的线程安全单例模式
ThreadLocal优化,使用ThreadLocal可以提高代码的复用性,感觉比较丢人,ThreadLocal的作用主要是复用代码
ThreadLocal优化,使用ThreadLocal可以提高代码的复用性,感觉比较丢人,ThreadLocal的作用主要是复用代码
【多线程:转账例子】探究两个对象对应两个线程如何加锁
【多线程:转账例子】探究两个对象对应两个线程如何加锁
327 0