2011-06-30 5 views
6

Lo siguiente pasará la prueba respondsToSelector, pero SIGABRT en la llamada real a [viewController selector] o [viewController action:selector]. La traza de pila indica 'NSInvalidArgumentException, razón: - [MyViewController selector]: selector no reconocido'.Enviando mensaje al objeto usando selector y NSSelectorFromString

[viewController @selector(selector)] causará un error de compilación (error: esperado ':' antes 'selector').

Cuando el selector está codificado, todo funciona bien.

¿Cómo envío un mensaje a un objeto a través de un selector?

-(void) notifyViewControllers:(NSString*) message 
{ 
    if(!message) return; 

    SEL selector = NSSelectorFromString(message); 
    if(!selector) return; 

    NSArray* viewControllers = [self.tabBarController viewControllers]; 
    if(!viewControllers) return; 

    for (UIViewController* viewController in viewControllers) 
    { 
     if(!viewController) continue; 

     if ([viewController respondsToSelector:selector]) { 
      // [viewController selector]; 
      [viewController action:selector]; 
     } 
    } 
} 

Respuesta

10
[self performSelector:@selector(notifyViewControllers:) withObject: message]; 
4

Trate

[viewController performSelector:selector]; 

Compruebe también otros métodos NSObject en 'familia' performSelector - con ellos se puede llamar fácilmente selector con retraso y/o el subproceso en segundo plano.

+0

Gracias Vladimir. Rakesh te ganó con eso (performSelector) - pero el tuyo fue precisamente el correcto. – jww

2

podría ser útil para saber cómo hacer esto donde no se puede utilizar performSelector, tal vez porque la cadena de selección debe ser utilizado dentro de un método de protocolo:

Con el fin de permitir que el selector de apoyo parámetros, lo que debería especificarse como sigue:

NSString *stringForSelector = @"doSomethingAwesome:"; // notice the colon 

Digamos que vamos a manejar un gesto de pulsar

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:NSSelectorFromString(stringForSelector)]; 

clase UIGestureRecognizer permite utilizar el reconocedor sí en la devolución de llamada de acción:

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer; 

Así que para hacer algo impresionante en portada, podemos escribir:

- (void)doSomethingAwesome:(UITapGestureRecognizer *)tapGesture 
{ 
    // gesture handling with UIGestureRecognizer availability 
} 
Cuestiones relacionadas