Supposons que j'ai l'interface Objective C SomeClass
qui a une méthode de classe appelée someMethod
:
@interface SomeClass : NSObject {
}
+ (id)someMethod;
@end
Dans une autre interface, je veux avoir une méthode d'assistance qui invoquerait dynamiquement someMethod
sur une classe comme celle-ci:
[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];
Quelle devrait être l'implémentation de invokeSelector
? Est-ce possible du tout?
- (void)invokeSelector:(SEL)aSelector forClass:(Class)aClass {
// ???
}
Au lieu de:
[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];
appel:
[[SomeClass class] performSelector:@selector(someMethod)];
Exemple (en utilisant GNUstep ...)
fichier A.h
#import <Foundation/Foundation.h>
@interface A : NSObject {}
- (NSString *)description;
+ (NSString *)action;
@end
fichier A.m
#import <Foundation/Foundation.h>
#import "A.h"
@implementation A
- (NSString *)description
{
return [NSString stringWithString: @"A"];
}
+ (NSString *)action
{
return [NSString stringWithString:@"A::action"];
}
@end
Ailleurs:
A *a = [[A class] performSelector:@selector(action)];
NSLog(@"%@",a);
Production:
2009-11-22 23:32:41.974 abc[3200] A::action
Belle explication de http://www.cocoabuilder.com/archive/cocoa/197631-how-do-classes-respond-to-performselector.html :
"Dans Objective-C, un objet de classe obtient toutes les méthodes d'instance de la classe racine pour sa hiérarchie. Cela signifie que chaque objet de classe qui descend de NSObject obtient toutes les méthodes d'instance de NSObject - y compris performSelector :."
Dans Objective-C, les classes sont également des objets. Cependant, les objets de classe sont traités différemment, car ils peuvent appeler les méthodes d'instance de leur classe racine (NSObject
ou NSProxy
dans Cocoa).
Il est donc possible d'utiliser toutes les méthodes d'instance définies dans NSObject
sur les objets de classe et la bonne façon d'invoquer dynamiquement une méthode de classe est:
[aClass performSelector:@selector(aSelector)];
Les Apple docs sont un peu plus spécifiques.
Vous ne devriez pas implémenter cela vous-même.
Le protocole NSObject a un performSelector:
méthode qui fait exactement cela.
Cette méthode intégrée est-elle ce que vous voulez?
id objc_msgSend(id theReceiver, SEL theSelector, ...)
(Voir les documents de référence d'exécution pour cette fonction.)