cómo crear una "matriz de selectores"


Estoy usando el SDK de iPhone (3.0) y estoy tratando de crear una matriz de selectores para invocar una variedad de métodos dentro de una clase.

Obviamente, estoy haciendo algo mal (creo que @selector no se considera una clase y, por lo tanto, rellenarlos en un NSArray no funciona).

Probé esto, pero obviamente está mal.

¿Hay una manera simple de tener una matriz de selectores como este? ¿O hay una mejor manera de iterar a través de una colección de métodos?

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;
}
Author: dcaswell, 2010-02-09

5 answers

¿Podría almacenar cadenas y usar NSSelectorFromString?

De los documentos

NSSelectorFromString

Devuelve el selector con un nombre dado.

SEL NSSelectorFromString (
   NSString *aSelectorName
);
 79
Author: blindjesse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-20 04:22:09

Esto crea un objeto a partir del selector:

[NSValue valueWithPointer:@selector(x)]
 40
Author: DenNukem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-09 16:03:11

¿Por qué no usar una simple matriz C?

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

...

for (int i = 0; i < sizeof(selectors)/sizeof(selectors[0]); i++) {
  [self performSelector:selectors[i]];
  // ....
}
 34
Author: kennytm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-09 16:12:13

También puede crear una matriz de NSInvocation s. Esto es útil si necesita un argumento para ir con su selector.

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
Author: Morrowless,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-30 04:42:37

Si la lista es estática, iría con la solución de KennyTM, pero si necesita un array dinámico o set, otra opción, además de almacenar la cadena de selector, es crear un objeto con una propiedad SEL o ivar, y almacenarlo.

@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

Entonces podría agregar un método perform a la clase también, e implementar la llamada al método allí.

 1
Author: big_m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-27 03:27:56