Objective-C pasando métodos como parámetros


¿Cómo se pasa un método como parámetro a otro método? Estoy haciendo esto a través de las clases.

Clase A:

+ (void)theBigFunction:(?)func{
    // run the func here
}

Clase B:

- (void)littleBFunction {
    NSLog(@"classB little function");
}

// somewhere else in the class
[ClassA theBigFunction:littleBFunction]

Clase C:

- (void)littleCFunction {
    NSLog(@"classC little function");
}

// somewhere else in the class
[ClassA theBigFunction:littleCFunction]
Author: bryanmac, 2011-10-29

4 answers

El tipo que está buscando es selector (SEL) y obtiene un selector de método como este:

SEL littleSelector = @selector(littleMethod);

Si el método toma parámetros, simplemente pon : donde van, así:

SEL littleSelector = @selector(littleMethodWithSomething:andSomethingElse:);

Además, los métodos no son realmente funciones, se utilizan para enviar mensajes a una clase específica (al comenzar con +) o instancia específica de la misma (al comenzar con -). Las funciones son de tipo C que realmente no tienen un "objetivo" como lo hacen los métodos.

Una vez que obtengas un selector, llamas a eso método en su destino (ya sea clase o instancia) como este:

[target performSelector:someSelector];

Un buen ejemplo de esto es UIControl's addTarget:action:forControlEvents: método que normalmente utiliza al crear UIButton u otros objetos de control mediante programación.

 45
Author: Filip Radelic,
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-10-29 02:18:23

Otra opción es mirar los bloques. Le permite pasar un bloque de código (un cierre) alrededor.

Aquí está una buena escritura para arriba en bloques:

Http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1

Aquí están los documentos de Apple:

Http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/00_Introduction.html

 7
Author: bryanmac,
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-10-29 02:02:06

El objetivo C hace que esta operación sea relativamente fácil. Apple proporciona esta documentación.

Para responder directamente a su pregunta, no está llamando a una función, sino a un selector. Aquí hay un código de ejemplo:

Función grande:

+ (void)theBigFunction:(SEL)func fromObject:(id) object{
    [object preformSelector:func]
}

Luego para la clase B:

- (void)littleBFunction {
    NSLog(@"classB little function");
}

// somewhere else in the class
[ClassA theBigFunction:@selector(littleBFunction) fromObject:self]

Luego para la clase C:

- (void)littleCFunction {
    NSLog(@"classC little function");
}

// somewhere else in the class
[ClassA theBigFunction:@selector(littleCFunction) fromObject:self]

EDITAR: Corregir selectores enviados (eliminar el punto y coma)

 7
Author: MJD,
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-10-29 02:39:29
 5
Author: ARC,
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-10-29 02:01:06