如何通过 NSInvocation 调用类方法



我们可以通过+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector NSObject得到NSMethodSignature。然后通过+ (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signature构建NSInvocation

这就是问题所在。我们只能得到实例的方法签名,类方法呢?

您可以通过以下方式获取类方法:

NSMethodSignature *pMS = [[YourObject class] methodSignatureForSelector: (SEL)aSelector];

片段[YourObject class]返回类对象(单一实例)的实例,然后可以使用该实例获取类方法。

补充:来自以下评论的新信息。 您可以执行以下操作:

NSMethodSignature *pMS = [YourObject methodSignatureForSelector: (SEL)aSelector];

下面是有关通过 NSInvocation 调用类(和实例方法)的其他详细信息,显示了methodForSignature:instanceMethodForSignature:

@interface SomeObject : NSObject
+ (void)instanceAndClass;
- (void)instanceAndClass;
+ (void)classOnly;
- (void)instanceOnly;
@end
@implementation SomeObject
+ (void)instanceAndClass { NSLog(@"Class version"); }
- (void)instanceAndClass { NSLog(@"Instance version"); }    
+ (void)classOnly { NSLog(@"Class only"); }
- (void)instanceOnly { NSLog(@"Instance only"); }
@end
@implementation Foo
- (void)invoke:(id)receiver signature:(NSMethodSignature *)signature selector:(SEL)selector {
    if (!signature) {
        NSLog(@"method signature is nil");
        return;
    }        
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.selector = selector;
    invocation.target = receiver;
    [invocation invoke];
}
- (void)foo {
    NSMethodSignature *signature;
    SomeObject *someObject = [SomeObject new];
    signature = [someObject methodSignatureForSelector:@selector(instanceAndClass)];
    [self invoke:someObject signature:signature selector:@selector(instanceAndClass)];
    // 2015-07-10 11:01:10.227 FooBar[65312:3097866] Instance version
    [self invoke:[someObject class] signature:signature selector:@selector(instanceAndClass)];
    // 2015-07-10 11:01:10.227 FooBar[65312:3097866] Class version
    signature = [someObject methodSignatureForSelector:@selector(classOnly)];
    [self invoke:someObject signature:signature selector:@selector(classOnly)];
    // 2015-07-10 11:01:10.227 FooBar[65312:3097866] method signature is nil
    signature = [[someObject class] methodSignatureForSelector:@selector(classOnly)];
    [self invoke:[someObject class] signature:signature selector:@selector(classOnly)];
    // 2015-07-10 11:01:10.228 FooBar[65312:3097866] Class only
    signature = [someObject methodSignatureForSelector:@selector(instanceOnly)];
    [self invoke:someObject signature:signature selector:@selector(instanceOnly)];
    // 2015-07-10 11:01:10.228 FooBar[65312:3097866] Instance only
    signature = [[someObject class] methodSignatureForSelector:@selector(instanceOnly)];
    [self invoke:[someObject class] signature:signature selector:@selector(instanceOnly)];
    2015-07-10 11:01:10.228 FooBar[65312:3097866] method signature is nil
    signature = [[someObject class] instanceMethodSignatureForSelector:@selector(instanceOnly)];
    [self invoke:someObject signature:signature selector:@selector(instanceOnly)];
    // 2015-07-10 11:01:10.228 FooBar[65312:3097866] Instance only
}

最新更新