NSInvocation简单使用 和 @encode方法的简单使用

来源:互联网 发布:淘宝上白酒好卖吗 编辑:程序博客网 时间:2024/05/17 02:22

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

一种是performSelector:withObject:

再一种就是NSInvocation

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

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

下面这个例子描述了如何使用NSInvocation,上代码:


AppDelegate类的.m文件


1、添加头文件

#import "MyClass.h"


2、在应用启动方法中添加代码:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.

    

   MyClass *myClass = [[MyClassalloc] init];

   NSString *myString = @"My string";

    

    //普通调用

   NSString *normalInvokeString = [myClass appendMyString:myString];

    NSLog(@"The normal invoke string is: %@", normalInvokeString);

    

    //NSInvocation调用

   SEL mySelector = @selector(appendMyString:);

    NSMethodSignature * sig = [MyClass

                              instanceMethodSignatureForSelector: mySelector];

    


    //获得返回值类型

   const char *returnType = sig.methodReturnType;

    //判断返回值类型是不是NSString

   if(strcmp(returnType,@encode(NSString *)) ==0)

    {

        NSLog(@"the returnType is NSString * and returnType is @");

        //注意,returnType并不是NSString *而是@,当然@encode(NSString *)的值也是@

       //这是因为:

        //为了更好的互操作性,Objective-C的数据类型,甚至自定义类型、函数或方法的元类型,都可以使用 ASCII 编码。@encode(aType) 可以返回该类型的 C字符串(char *)的表示

        //比如 @encode(int)的值是i@encode(MyClass) {MyClass=#}@encode(void) v@encode(id)也是 @@encode(NSString)也是 {NSString=#}@encode(void *) ^v

    }

    

    


    

    

   NSInvocation * myInvocation = [NSInvocationinvocationWithMethodSignature: sig];

    //设置调用者也就是AsynInvoked的实例对象

    [myInvocationsetTarget:myClass];

    //设置被调用的方法

    [myInvocationsetSelector:mySelector];

    //如果此消息有参数需要传入,那么就需要按照如下方法进行参数设置,需要注意的是,atIndex的下标必须从2开始。原因为:0 1 两个参数已经被target selector占用

    //&myString是指向指针myString的指针

    [myInvocationsetArgument:&myString atIndex: 2];

    

    

    //retain 所有参数,防止参数被释放dealloc

    [myInvocationretainArguments];

    //方法调用

    [myInvocationinvoke];

    

    //声明返回值变量

   NSString * result = nil;

    //如果返回值为对象,那么为变量赋值

    [myInvocationgetReturnValue: &result]; //&result是指向指针result的指针

    NSLog(@"The NSInvocation invoke string is: %@", result);

    

/*

    //也可以通过得到返回值的长度,根据长度申请内存空间,然后赋值

 

 

    //返回值长度,可以根据该值为返回的值创建内存空间

    NSUInteger length = [sig methodReturnLength];

    //根据长度申请内存

    void *buffer = (void *)malloc(length);

    //为变量赋值

    [myInvocation getReturnValue:buffer];

*/

    

    [myClassrelease];

    

    return YES;

}



创建MyClass类的.h和.m文件

1、MyClass.h文件


#import <Foundation/Foundation.h>


@interface MyClass :NSObject

{


}


- (NSString *)appendMyString:(NSString *)string;


@end



2、MyClass.m文件


#import "MyClass.h"


@implementation MyClass


- (id)init

{

   self = [superinit];

   if (self) {

        // Initialization code here.

    }

    

    return self;

}


- (NSString *)appendMyString:(NSString *)string

{

   NSString *mString = [NSStringstringWithFormat:@"%@ after append method", string];

    

   return mString;

}


- (void)dealloc

{

    [superdealloc];

}

@end

以上,代码可以运行了,祝你好运


原创粉丝点击