2012-06-05 18 views
5

Possiamo ottenere NSMethodSignature entro il + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector di NSObject. Quindi costruire NSInvocation per + (NSInvocation *)invocationWithMethodSignature:(NSMethodSignature *)signatureCome posso richiamare un metodo di classe da NSInvocation?

Ecco il problema. Possiamo solo ottenere la firma del metodo dell'istanza , e il metodo della classe?

risposta

7

È possibile ottenere i metodi della classe da:

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

Il frammento [YourObject class] restituisce un'istanza dell'oggetto di classe (Singleton), che è possibile utilizzare per ottenere metodi della classe.

AGGIUNGI: Nuove informazioni dai commenti qui sotto. Si può solo effettuare le seguenti operazioni:

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

Non hai nemmeno bisogno la parte 'class'. Puoi semplicemente inviarlo a "YourObject", e funzionerà ancora, dato che i nomi di classe sono anche oggetti di prima classe oltre a essere typedef. –

+0

Buono a sapersi! grazie;) – Kent

+0

Grazie! Ma funzionerà solo con il metodo dichiarato come metodo di istanza che viene avviato da '-'. Non riesco a ottenere che methodSignature sia dichiarato come metodo di classe che è stato avviato da '+' –

1

Ecco ulteriori dettagli circa invocando classe (e metodi di istanza) tramite NSInvocation mostrando methodForSignature: e 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

Carichi di aiuto. Grazie. –

Problemi correlati