2010-02-09 12 views
80

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

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

Intenté esto, pero obviamente está mal.

¿Hay una manera simple de tener una variedad 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; 
} 

Respuesta

79

Podría almacenar cadenas y utilizar NSSelectorFromString?

Desde el docs

NSSelectorFromString 

como resultado el selector con un nombre dado.

SEL NSSelectorFromString (
    NSString *aSelectorName 
); 
+0

me parece bien. ¡Gracias! – user141146

+0

No es una solución adecuada para cuando solo se necesita una selección de selectores. –

40

Esto crea un objeto fuera del selector:

[NSValue valueWithPointer:@selector(x)] 
+2

¿Cómo haría para extraer el selector de esto para ser utilizado por 'performSelector:'? –

+3

@DeanKelly respondió aquí http://stackoverflow.com/questions/575055/how-to-build-a-nsarray-or-nsmutablearray-of-class-methods-in-objective-c por terry franguiadakis –

+0

Se necesita yeso de tipo , como sigue, 'SEL x = (SEL) selectorValue.pointerValue;' –

34

¿Por qué no utilizar una matriz simple en C?

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

... 

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

Bueno, pero 'static' no es necesario aquí (el inicializador no es una constante en tiempo de compilación). –

+0

¡esta respuesta necesita más votos! –

12

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 
+0

NSInvocación es demasiado caro. –

1

Si la lista es estática, me gustaría ir con la solución de KennyTM, pero si necesita una matriz dinámica o conjunto, otra opción, además de almacenar la cadena de selección, es crear un objeto con una propiedad SEL o ivar, y almacenar eso.

@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 se podría añadir un método perform a la clase, así, e implementar la llamada al método allí.

Cuestiones relacionadas