Cocoa 拾遗 —— NSInvocation

作者: StanOz | 来源:发表于2016-08-11 21:52 被阅读73次

    这是对于 Cocoa/Cocoa Touch 框架的查漏补缺行动,也是对平时不常用的、零碎的知识的总结。不积跬步,无以至千里嘛。这次的主角是 NSInvocation。🌚

    NSInvocation

    NSInvocation 的文档 说明这个类的作用。它的实例封装了一个动作,包含了 Objective-C 中消息的所有元素:target,selector,arguments 和 return value。

    NSInvocation 只有 +invocationWithMethodSignature: 一个类方法获得实例,需要 NSMethodSignature 实例作为参数,之后还需设置它的 selector 属性。因为除了通过 NSMethodSignature 实例得到参数类型和返回值类型的信息之外,还需知道方法的名字,不然无法找到方法实现的地址,更不可能调用方法实现那段子程序。

    下面的代码创建了一个 NSInvocation 对象并执行:

    @interface TestClass : NSObject
    -(NSString *)greet:(NSString *)str;
    @end
    
    @implementation TestClass
    -(NSString *)greet:(NSString *)str {
        NSString *greetStr = [NSString stringWithFormat:@"Hello, %@!", str];
        return greetStr;
    }
    @end
        
    int main (int argc, char *argv[]) {
        TestClass *tester = [[TestClass alloc] init];
        NSString *string = @"Stan";
        NSString * returnString;
        
        NSMethodSignature *signture = [TestClass instanceMethodSignatureForSelector:@selector(greet:)];
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signture];
        [invocation setTarget:tester];
        [invocation setSelector:@selector(greet:)];
        [invocation setArgument:&string atIndex:2];
        [invocation invoke];
        [invocation getReturnValue:&returnString];
        NSLog(@"%@", returnString);
        return 0;
    }
    

    注意点

    1. -setArgument: 的 index 一定是从2开始的,0和1已经被作为为隐式传递的参数 self_cmd 占据;
    2. -setArgument: 不会 retain 传入的参数,这意味着在 invoke 之前要保证作为参数的对象不被释放,你可以通过 -retainArguments 去 retain 参数;
    3. NSTimer+scheduledTimerWithTimeInterval:invocation:repeats: 方法中会通过 -retainArguments 去 retain 参数,添加一个 symbolic breakpoint 可以证明这一点;
    4. 如果返回值不是 Objective-C 中的对象,需要从方法签名中得到返回值占用空间的大小(methodReturnLength 属性),并通过 void *buffer = malloc(size) 分配空间,把返回值的内容拷贝到 buffer 指向的空间去;
    5. -getReturnValue: 当然要在 -invoke 之后执行,否则结果是未定义的。

    相关文章

      网友评论

        本文标题:Cocoa 拾遗 —— NSInvocation

        本文链接:https://www.haomeiwen.com/subject/gdussttx.html