zoukankan      html  css  js  c++  java
  • ios NSInvocation

    转载自:http://blog.csdn.net/cancer1617/article/details/6855484

               http://blog.csdn.net/volcan1987/article/details/6690208尊重原创!

    在 iOS中可以直接调用 某个对象的消息 方式有2种:

    一种是performSelector:withObject:

    再一种就是NSInvocation

    第一种方式比较简单,能完成简单的调用。但是对于>2个的参数或者有返回值的处理,那就需要做些额外工作才能搞定。那么在这种情况下,我们就可以使用NSInvocation来进行这些相对复杂的操作

    NSInvocation可以处理参数、返回值。会java的人都知道反射操作,其实NSInvocation就相当于反射操作。

    #import <Foundation/Foundation.h>
    #import "MyClass.h"
    
    int main (int argc, const char * argv[])
    {
    
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
        MyClass *myClass = [[MyClass alloc] init];
        NSString *myString = @"My string";
        
        //普通调用
        NSString *normalInvokeString = [myClass appendMyString:myString];
        NSLog(@"The normal invoke string is: %@", normalInvokeString);
        
        //NSInvocation调用
        SEL mySelector = @selector(appendMyString:);
       //方法签名类,需要被调用消息所属的类AsynInvoke ,被调用的消息invokeMethod:
        NSMethodSignature * sig = [[myClass class] 
                                   instanceMethodSignatureForSelector: mySelector];
        //根据方法签名创建一个NSInvocation
        NSInvocation * myInvocation = [NSInvocation invocationWithMethodSignature: sig];
        //设置调用者也就是myClass 的实例对象
        [myInvocation setTarget: myClass];
        //设置被调用的消息
        [myInvocation setSelector: mySelector];
    
        //如果此消息有参数需要传入,那么就需要按照如下方法进行参数设置,需要注意的是,atIndex的下标必须从2开始。原因为:0 1 两个参数已经被target 和selector占用
        [myInvocation setArgument: &myString atIndex: 2];    
        //retain 所有参数,防止参数被释放dealloc
        [myInvocation retainArguments]; 
        //消息调用  
        [myInvocation invoke];
    
        //获得返回值类型
       const char *returnType = sig.methodReturnType;
    
        //声明返回值变量
       id returnValue;
        //如果没有返回值,也就是消息声明为void,那么returnValue=nil
       if( !strcmp(returnType, @encode(void)) ){
             returnValue =  nil;
       } else if( !strcmp(returnType, @encode(id)) ){//如果返回值为对象,那么为变量赋值
                [invocation getReturnValue:&returnValue];
            }else{//如果返回值为普通类型NSInteger  BOOL
               //返回值长度
            NSUInteger length = [sig methodReturnLength];
               //根据长度申请内存
            void *buffer = (void *)malloc(length);
              //为变量赋值
           [invocation getReturnValue:buffer];
    //以下代码为参考:具体地址我忘记了,等我找到后补上,(很对不起原作者)
    
    if( !strcmp(returnType, @encode(BOOL)) ) {
    returnValue = [NSNumber numberWithBool:*((BOOL*)buffer)];
    }
    
    else if( !strcmp(returnType, @encode(NSInteger)) ){
    returnValue = [NSNumber numberWithInteger:*((NSInteger*)buffer)];
    }
    
    returnValue = [NSValue valueWithBytes:buffer objCType:returnType];
    }
        [myClass release];
        
        [pool drain];
        return 0;
    }
  • 相关阅读:
    Flask_自定义参数类型(自定义转换器)
    数据结构与算法(排序)
    数据结构与算法(查找)
    Vue_fetch和axios数据请求
    Vue_修饰符
    Vue_列表过滤应用
    Vue_生命周期函数
    Vue_watch()方法,检测数据的改变
    Django_redis_缓存
    防火墙相关
  • 原文地址:https://www.cnblogs.com/wyqfighting/p/3253378.html
Copyright © 2011-2022 走看看