NSInvocation的使用

2019-05-07  本文已影响0人  Claudlit

转载自jiangamh. 原文地址

-(void)method1Test{
    NSLog(@"method1Test");
}
-(NSInteger)mehtod2Test{
    NSLog(@"method2Test");
    return 1;
}
-(ViewController*)method3Test:(NSString*)str{
    NSLog(@"参数:%@",str);
    return self;
}

- (void)viewDidLoad{
    [super viewDidLoad];
    [self nsInvocationTest];
}

-(void)nsInvocationTest
{
    //情况一 无参数,无返回值
    //通过选择器获取方法签名
    SEL selector = @selector(method1Test);
    NSMethodSignature *methodSign = [[self class] instanceMethodSignatureForSelector:selector];
    
    NSInvocation *methodInvocation = [NSInvocation invocationWithMethodSignature:methodSign];//通过方法签名获得调用对象
    [methodInvocation setSelector:selector]; //设置selector
    [methodInvocation setTarget:self];       //设置target
    [methodInvocation invoke];               //执行
    
    //情况二 有返回值,无参数
    selector = @selector(mehtod2Test);
    methodSign = [[self class] instanceMethodSignatureForSelector:selector];
    
    NSInvocation *mehtod2Invocation = [NSInvocation invocationWithMethodSignature:methodSign];
    [mehtod2Invocation setSelector:selector];   //设置selector
    [mehtod2Invocation invokeWithTarget:self];  //设置target 并执行
    
    NSInteger returnValue = 0;
    [mehtod2Invocation getReturnValue:&returnValue];  //获取返回值
    NSLog(@"method2Test返回值:%ld",returnValue);
    
    //情况三 有返回值,有参数
    selector = @selector(method3Test:);
    NSMethodSignature *method3Sign = [[self class] instanceMethodSignatureForSelector:selector];
    NSInvocation *method3Invocation = [NSInvocation invocationWithMethodSignature:method3Sign];
    [method3Invocation setSelector:selector]; //设置selector
    [method3Invocation setTarget: self];      //设置target
    NSString *arg1 = @"testArg1";
    [method3Invocation setArgument:&arg1 atIndex:2];  //设置参数
    [method3Invocation invoke];                       //执行

    //获取返回值
    /**
    崩溃: 当返回值为对象是,arc情况下容易出现崩溃问题,如下两种解决方案。
    原因: arc下vc如果用strong的,默认NSInvocation实现认为,已经对返回对象retain一次,实际上并没有,当返回对象出了作用域时候,已经被收回。导致崩溃。
    */
    //解决方案1
    void *vc = nil;
    [method3Invocation getReturnValue:&vc];
    NSLog(@"vc:%@",(__bridge ViewController*)vc);
    
    //解决方案2
    UIViewController * __unsafe_unretained vc = nil;
    [method3Invocation getReturnValue:&vc];
    NSLog(@"vc:%@",vc);
}

上一篇下一篇

猜你喜欢

热点阅读