Variadic methods in Objective C

Autor: | Última modificación: 15 de noviembre de 2022 | Tiempo de Lectura: 2 minutos
Temas en este post:

Methods that accept a variable number of parameters

It’s very common in Cocoa to find methods that take a variable number of parameters (ending in nil). For example, see NSArray’s arrayWithObjects: or dictionaryWithObjectsAndKeys: in NSDictionary.

In both cases, the method will loop through our list processing each element until it reaches the nil. So let’s see how to use Variadic methods in Objective C.

How to create our own variadic methods in Objective C

The plumbing necessary for variadic methods is not Objective C specific, but rather «inherited» form the older C substrate. Usage of variadic functions is very common in C (see printf) and is described in the The Bible according to Kernighan & Ritchie. It’s on chapter 7 of my copy of «The C Programming Language» (in Spanish).

Creating a variadic method in Objective C is similar to creating a variadic function in C as described by Kernighan & Ritchie.

Dennis Ritchie
Dennis M. Ritchie: So long and thanks for all the code.

To create a variadic method, you must first define at least a single parameter. This will always work, even for empty lists, as  you’ll never forget to provide the ending nil. 😉 Therefore, even empty lists will consist in at least one element: nil.

Within your method, you need to define a variable with type va_list that represents a pointer to the first element of the list of parameters. You will also need to call the va_start macro. This will initialize your va_list so it points to the first element.

While you process the elements of the list, you must call va_args to obtain a pointer to the next  element.

Once finished, call va_end for cleanup.

Example of variadic method in Objective C

A simple method that takes a variable sized list of strings (NSString) and returns the number of strings it received:

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

    va_list words; // Lista de palabras
    va_start(words, firstWord); // Points to the first element
    int i = 0;
    NSString * word;
    for (word = firstWord; word; word = va_arg(words, NSString*), i++) {
        NSLog(@"#%d: %@", i, word);
    }
    va_end(words);
    return ++i;

}