zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    内存条的物理结构分析【转载】
    JDK动态代理[2]----动态代理设计模式(文章转载于别处)
    shell 计算
    如何使用Vagrant创建linux环境(MacOS版)
    JavaFreemarker01快速上手
    7、验证信息
    6、更新文档
    5、删除文档
    4、查询文档02
    3、查询文档01
  • 原文地址:https://www.cnblogs.com/gugupluto/p/3165031.html
Copyright © 2011-2022 走看看