Why does NSArray arrayWithObjects require a terminating nil?

It all has to do with the C calling ABI.

Consider these methods:

- (id)initWithFormat:(NSString *)format, ...;
+ (id)arrayWithObjects:(id)firstObj, ...;
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;

The ... tells the compiler that a variable number of arguments of any type may be present. There is no way for the compiler to know what those types are required to be (the real definitions have markers that help with that).

Now, consider the three methods. All three have vastly different requirements for what might be present in the variable argument list. An array must be a bunch of objects followed by a nil. The dictionary requires a bunch of pairs of objects followed by a nil. Finally, the string method requires a bunch of arguments that match the types in the format string.

All of these behaviors are directly tied to the method being invoked and, if the author of an API decided to go for “hard to use”, the behavior of decoding the variable arguments could be modified at runtime, just to make life difficult.

Bottom line: The C ABI doesn’t have a syntax that allows for specifying that a method or function takes a variable number of arguments with any kind of set of constraints on the arguments or their termination.

Objective-C could change the rules just for method declarations & invocations, but that wouldn’t help with C functions or C++, both of which Objective-C must remain compatible with.

Leave a Comment