Cómo crear métodos variádicos en Objective C

Contenido del Bootcamp dirigido por:

Recordando a Dennis Ritchie
¿Qué encontrarás en este post?

Métodos variádicos en Objective C

Es muy común en Cocoa encontrarnos con métodos que aceptan una lista de parámetros, terminando en nil. Por ejemplo, tenemos en NSArray a arrayWithObjects: o dictionaryWithObjectsAndKeys: en NSDictionary. En todos estos casos, el método recorre la lista que le hemos dado, procesando los elementos, hasta que se encuentra con el nil; punto en el que se detiene.

Cómo crear métodos variádicos en Objective C

Las facilidades existentes para crear métodos variádicos no son propias de Objective C, sino que son «heredadas» de C. Su uso es también sumamente común en C (ver printf) y está descrito en el capítulo 7 de la Biblia según Kernighan & Ritchie.

Recordando a Dennis Ritchie_métodos "variádicos" en Objective C
Recordando a Dennis Ritchie

Para crear métodos varíadicos en Objective C, hay que definir al menos un parámetro con tipo y nombre. Esto siempre será válido, incluso para listas vacías, ya que habrá al menos el elemento final (nil).

Dentro del método hemos de definir una variable de tipo va_list que representa un puntero al principio de la lista de parámetros. Luego hemos de llamar a la macro va_start para que inicialice nuestra va_list al primer elemento de la lista.

A medida que vamos procesando los elementos, hemos de ir llamando a va_args para obtener un puntero al elemento siguiente.

Al terminar, hemos de llamar a va_end para que haga limpieza.

Ejemplo de método variádico en Objective C

Echad un vistazo al siguiente ejemplo de métodos variádicos Objective,  supongamos un método muy sencillo que acepta una lista variable de cadenas (NSString) y devuelve el número de cadenas que ha recibido:

-(int) countWords: (NSString *)firstWord, ...{

    va_list words; // Lista de palabras
    va_start(words, firstWord); // Apuntamos al primer elemento de la lista
    int i = 0;
    NSString * word;
    for (word = firstWord; word; word = va_arg(words, NSString*), i++) {
        NSLog(@"#%d: %@", i, word);
    }
    va_end(words);
    return ++i;

}