NSInvocation

时间:2023-03-10 06:03:42
NSInvocation

NSInvocation

基本简介

NSInvocation是一个静态描绘的OC消息,也就是说,它是一个动作,这个动作可以变成一个对象。NSInvocation对象在对象和对象之间和应用程序和应用程序之间被用于存储和向前信息。

一个ISInvocation对象包括了所有OC消息的基本元素:目标,selector,参数和返回值。每个元素都可以直接设置,返回值是在NSInvocation对象发送的时候自动设置的。

一个NSInvocation对象可以被反复地发送给不同的目标;为了得到不同的结果,它的参数也可以在发送的时候直接修改;甚至它的selector也可以被修改为另一个,这个另一个和上一个需要有相同的方法签名(参数和返回类型)。这种灵活性使得NSInvocation非常有用在使用许多参数和变化的情况下重新发送消息,而不是为了发送消息而重新输入细小的改变。在发送消息到一个新的target前你可以修改NSInvocation对象。

NSInvocation不支持调用方法的参数。你应该使用invocationWithMethodSignature:这个类方法去创建NSInvocation对象,而不是使用alloc init.

例子

比如现在有个CurrentDate类,其中有个方法:

-(NSString *)stringForDate:(NSDate *)date usingFormatter:(NSDateFormatter *)formatter;

那么在ViewController中调用你可以有以下几种调用方式:

  • 原始调用

         NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"YYYY-MM-dd"];
    CurrentDate *currentDateClassObject = [[CurrentDate alloc] init];
    NSString *currentDate = [currentDateClassObject stringForDate:[NSDate date] usingFormatter:dateFormat]; NSLog(@"currentDate:%@",currentDate);
  • NSInvocation调用

     //NSInvocation调用
    //方法签名类,需要被调用消息所属的类CurrentDate,被调用的消息stringForDate:usingFormatter:
    SEL mySelector = @selector(stringForDate:usingFormatter:);
    NSMethodSignature *sig = [[currentDateClassObject class] instanceMethodSignatureForSelector:mySelector];
    //根据方法签名创建一个NSInvocation
    NSInvocation *myInvocation = [NSInvocation invocationWithMethodSignature:sig];
    //设置调用者
    [myInvocation setTarget:currentDateClassObject];
    //设置被调用的消息
    [myInvocation setSelector:mySelector];
    //如果此消息有参数需要传入,那么就需要按照如下方法进行参数设置,需要注意的是,atIndex的下标必须从2开始。原因为:0 1 两个参数已经被target 和selector占用
    NSDate *myDate = [NSDate date];
    [myInvocation setArgument:&myDate atIndex:2]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"YYYY-MM-dd"];
    [myInvocation setArgument:&dateFormatter atIndex:3];
    NSString *result = nil; //retain所有参数,防止参数被释放
    [myInvocation retainArguments];
    //消息调用
    [myInvocation invoke];
    //获取消息返回的信息
    [myInvocation getReturnValue:&result];
    NSLog(@"The result is :%@ ",result);

附: