为什么NSArray arrayWithObjects需要终止nil?

pjb*_*jb3 16 objective-c

我知道它标志着一组varargs的结束,但为什么不能以不需要nil的方式实现呢?

bbu*_*bum 18

这一切都与C呼叫ABI有关.

考虑以下方法:

- (id)initWithFormat:(NSString *)format, ...;
+ (id)arrayWithObjects:(id)firstObj, ...;
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
Run Code Online (Sandbox Code Playgroud)

...告诉编译器的任何类型的参数的变量数目可以存在.编译器无法知道这些类型需要什么(真正的定义具有帮助它的标记).

现在,考虑三种方法.这三者对变量参数列表中可能存在的内容有着截然不同的要求.数组必须是一堆对象后跟一个nil.字典需要一堆对象后跟一个零.最后,string方法需要一堆与格式字符串中的类型匹配的参数.

所有这些行为都与被调用的方法直接相关,如果API的作者决定"难以使用",解码变量参数的行为可能会在运行时被修改,只会让生活变得困难.

底线:C ABI没有允许指定方法或函数采用可变数量的参数以及参数或其终止的任何类型的约束的语法.

Objective-C可以改变方法声明和调用的规则,但这对C函数或C++没有帮助,这两者都与Objective-C保持兼容.

  • Ken,在NSArray等特定类的编译器中加入特殊情况会打开一大堆蠕虫.如果你继承NSArray怎么办? (2认同)