2012-06-05 10 views
5

Podemos obtener NSMethodSignature por + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector de NSObject. A continuación, construya NSInvocation por + (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signature¿Cómo puedo invocar un método de clase mediante NSInvocation?

Aquí está el problema. Solo podemos obtener la firma de método de instancia, ¿qué tal el método de clase?

Respuesta

7

Usted puede obtener los métodos de la clase por:

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

El fragmento [YourObject class] devuelve una instancia de la clase de objeto (Singleton) que luego se puede utilizar para obtener los métodos de clase.

ADD: Nueva información de los comentarios a continuación. Usted sólo puede hacer lo siguiente:

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

Ni siquiera necesita la 'parte class'. Puedes simplemente enviarlo a 'YourObject', y seguirá funcionando, ya que los nombres de las clases también son objetos de primera clase, además de ser typedefs. –

+0

¡Es bueno saberlo! thx;) – Kent

+0

¡Gracias! Pero esto solo funcionará con el método declarado como método de instancia que se inicia con '-'. No puedo obtener el método Firma declarada como método de clase que se inicia con '+' –

1

Aquí está el detalle adicional sobre la invocación de la clase (y métodos de instancia) a través de NSInvocation mostrando methodForSignature: y 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 
} 
+0

Un montón de ayuda. Gracias. –

Cuestiones relacionadas