web-dev-qa-db-fra.com

Comment créer un "tableau de sélecteurs"

J'utilise le SDK de l'iPhone (3.0) et j'essaie de créer un tableau de sélecteurs pour invoquer diverses méthodes au sein d'une même classe.

De toute évidence, je fais quelque chose de mal (je pense que @selector n'est pas considéré comme un cours et donc le ranger dans un NSArray ne fonctionne pas).

J'ai essayé cela, mais c'est évidemment faux. 

Y at-il un moyen simple d'avoir un tableau de sélecteurs comme celui-ci? Ou existe-t-il un meilleur moyen de parcourir différentes méthodes?

selectors = [NSArray arrayWithObjects:
                          @selector(method1),
                          @selector(method2),
                          @selector(method3),
                          @selector(method4),
                          @selector(method5),
                          @selector(method6),
                          @selector(method7), nil];

for (int i = 0; i < [selectors count]; i++) {
    if ([self performSelector:[selectors objectAtIndex:i]]) // do stuff;
}
81
user141146

Pourriez-vous stocker des chaînes et utiliser NSSelectorFromString? 

De la docs

NSSelectorFromString

Retourne le sélecteur avec un nom donné.

SEL NSSelectorFromString (
   NSString *aSelectorName
);
79
blindjesse

Cela crée un objet hors du sélecteur: 

[NSValue valueWithPointer:@selector(x)]
40
DenNukem

Pourquoi ne pas simplement utiliser un tableau C simple?

static const SEL selectors[] = {@selector(method1),
                                ....
                                @selector(method7)};

...

for (int i = 0; i < sizeof(selectors)/sizeof(selectors[0]); i++) {
  [self performSelector:selectors[i]];
  // ....
}
34
kennytm

Vous pouvez également créer un tableau de NSInvocations. C'est pratique si vous avez besoin d'un argument pour aller avec votre sélecteur.

NSMethodSignature *sig = [[yourTarget class] instanceMethodSignatureForSelector:yourSEL];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
[inv setTarget:yourTarget];
[inv setSelector:yourSEL];
[inv setArgument:&yourObject atIndex:2]; // Address of your object
12
Morrowless

Si la liste est statique, je choisirais la solution de KennyTM, mais si vous avez besoin d'un tableau ou d'un ensemble dynamique, une autre option, outre le stockage de la chaîne de sélecteur, consiste à créer un objet avec une propriété SEL ou ivar et à le stocker.

@interface SelectorObject : NSObject
@property (assign, readonly, nonatomic) SEL selector;
- (id)initWithSelector:(SEL)selector;
@end

@implementation SelectorObject
- (id)initWithSelector:(SEL)selector {
  self = [super init];
  if (self) {
    _selector = selector;
  }
  return self;
}
@end

Vous pouvez ensuite ajouter une méthode perform à la classe et y implémenter l'appel de méthode.

1
big_m

NSPointerArray est ce que vous voulez, je pense. SEL est un objet opaque, tel que doc Apple said

NSPointerArray *selectors = [[NSPointerArray alloc] initWithOptions: NSPointerFunctionsOpaqueMemory];
[selectors addPointer:@selector(onSendButton:)];
[button addTarget: self action:[selectors pointerAt:0] forControlEvents:UIControlEventTouchUpInside];

Je pense que la mutabilité est très utile. Le tableau de style C ne peut pas être modifié, sauf que vous utilisez malloc/free.

SEL selectors[] = { @selector(onSendButton:) };
[button addTarget: self action:selectors[0] forControlEvents:UIControlEventTouchUpInside];

c’est simple, mais ce n’est pas flexible ..__ Choisissez à votre guise.

0
DawnSong