• NSInvocation简单总结


    (1)用法

     NSInvocation是调用函数的另一种方式,它将调用者,函数名,参数封装到一个对象,然后通过一个invoke函数来执行被调用的函数,其思想就是命令者模式,将请求封装成对象。

    例如,有这样一个类:

    @implementation CA

    -(int)AddA:(int)a andB:(int)b

    {   

          return a + b;

    }

    @end

     

    一般调用函数的方式是:

    CA *ca = [CA new];

    int result = [ca AddA:2 andB:3];

     

    或者用performSelector,但是后者只能有一个参数,所以对于有多个参数的情况,就可以用NSInvocation来调用。

    示例代码:
    
     
    
        CA *ca = [CA new];
    
        NSMethodSignature *sig= [[CA class] instanceMethodSignatureForSelector:@selector(AddA:andB:)]; //根据selector得到一个签名对象
    
        NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:sig];//根据该签名对象创建一个NSInvocation对象
    
        invocation.target = ca;//指定调用函数的对象
    
        invocation.selector = @selector(AddA:andB:);//指定要调用的函数名
    
        int a = 20;
    
        int b = 30;
    
        
    
        [invocation setArgument:&a atIndex:2];//指定参数,以指针方式,并且第一个参数的起始index是2,因为index为1,2的分别是self和selector
    
        [invocation setArgument:&b atIndex:3];
    
        [invocation retainArguments];//因为NSInvocation不会自己去retain参数,因此需要用户去retain,当然本例中其实没必要
    
          [invocation invoke];
    
     
        //获取返回值的过程略有点复杂,需要根据起类型长度分配空间,然后转为对象
    
        //如果是int,BOOL等简单类型,返回的对象是NSNumber
    
        //如果是其他类型的对象,返回的对象是NSValue
    
         //判断返回值类型,用strcmp(returnType, @encode(NSInteger))
    
     
    
        const char *returnType = sig.methodReturnType;
    
        id returnValue;
    
        NSUInteger length = [sig methodReturnLength];
    
        void *buffer = (void *)malloc(length);
    
        [invocation getReturnValue:buffer];
    
        returnValue = [NSNumber numberWithInteger:*((NSInteger*)buffer)];//int的情况
    
        //returnValue = [NSNumber numberWithBool:*((BOOL*)buffer)]; //bool 的情况
    
          //returnValue = [NSValue valueWithBytes:buffer objCType:returnType];// 其他类型的情况
    
        
    
        int result = [returnValue intValue];
    
        NSLog(@"result=%d",result);
    

      

     

    (2) 用到NSInvocation的一些场合

        [NSTimer scheduledTimerWithTimeInterval:0.1 invocation:invocation repeats:YES]

     

        NSInvocationOperation //它是NSOperation的派生类,用NSInvoation来初始化

     

        (void)forwardInvocation:(NSInvocation *)anInvocation

        这个函数与forwardTargetWithSelector类似,当某个对象收到一个selector消息,但该对象没有实现该selector,且实现forwardInvocation,那么系统会构造一个NSInvocation对象,并调用forwardInvocation,这样在函数里面,用户就可以用[invocation invokeWithTarget:friend];来让另一个对象来执行这个selector.

          要实现这个函数,还必须实现methodSignatureForSelector,因为这个anInvocation是系统构造的,构造这个对象需要有签名对象,这个对象必须由用户提供。所以这个函数用起来比forwardingTargetForSelector麻烦 

        另外,由于使用forwardInvocation可以使得一个对象将它没有实现的方法转发给其他对象,因此可以变相的实现多继承。

     

    参考链接:http://www.cnblogs.com/pengyingh/articles/2359199.html

  • 相关阅读:
    麻省理工算法导论学习笔记(1)算法介绍
    麻省理工算法导论学习笔记(2)渐近符号、递归及解法
    Mybatis if 标签 判断不生效
    Linux permission denied解决方法?
    MySQL查找是否存在
    List集合数据去重
    Java获取list集合的前几个元素
    git如何新建(修改)分支
    asp.net下url参数含有中文读取后为乱码
    时间复杂度为O(n)的排序算法
  • 原文地址:https://www.cnblogs.com/gugupluto/p/3165031.html
Copyright © 2020-2023  润新知