可变参数之后的参数
Objective-C,特别是 Cocoa,支持可变参数,例如 NSString +(NSString *)stringWithFormat:(NSString *)string, ....
上的类方法。
现在,我想知道的是是否可以遵循可变参数必须位于方法的末尾,或者该方法可以在此之后继续吗?
举个例子,假设我有可变参数方法(带有适当的宏),
- (void)setObjects:(id)obj, ... NS_REQUIRES_NIL_TERMINATION;
如果我想在特定索引处使用它,我可以做这样的事情吗?
- (void)setObjects:(id)obj, ... NS_REQUIRES_NIL_TERMINATION atIndex:(int)index;
我一直在尝试,但这个特定的例子不起作用,给我一条错误消息,内容为“预期 ';'”在方法原型之后”。当然,我可以打乱参数以确保可变参数位于末尾,就像这样,
- (void)atIndex:(int)index setObjects:(id)obj, ... NS_REQUIRES_NIL_TERMINATION;
这当然有效,但对我来说,它在 Cocoa 命名约定中感觉相当陌生——这对我来说是一个问题。
谢谢你,
Objective-C, or Cocoa specifically, supports variadic arguments, like for example class the method on NSString +(NSString *)stringWithFormat:(NSString *)string, ....
.
Now, what I would like to know is if it is possible to follow that variadic argument must be at the end of the method, or can the method continue after that?
As an example, suppose I have the variadic method (with the appropriate macro),
- (void)setObjects:(id)obj, ... NS_REQUIRES_NIL_TERMINATION;
If I want to use it at a specific index, could I do something like this,
- (void)setObjects:(id)obj, ... NS_REQUIRES_NIL_TERMINATION atIndex:(int)index;
I've been trying, and this specific example doesn't work, giving me an error message saying "Expected ';' after method prototype". Of course, I could shuffle the arguments around to make sure the variadic one is at the end, like this,
- (void)atIndex:(int)index setObjects:(id)obj, ... NS_REQUIRES_NIL_TERMINATION;
This certainly works, but to me it feels rather alien amidst the Cocoa naming conventions -- which is a problem for me.
Thank you,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可变参数必须是最后一个参数。这是因为 Objective-C 中的方法实际上只是一个伪装的普通 C 函数,并且 C 也不允许在可变参数之后有任何参数。
C 不允许它的原因与 C 支持的调用约定有关。当您调用可变参数函数时,首先实际上并不知道该函数的可变参数数量。不同的函数可以用不同的方式来计算它。在 Objective C 中,用
nil
终止可变参数是很常见的。printf
函数根据格式字符串计算出它传递了多少个参数。由于函数最初不知道有多少个可变参数,因此它无法知道可变参数列表之后的参数的内存位置。如果您想了解更多信息,请查阅“C 调用约定”。
(有些人认为这个限制是 C 语言的“疣”,这是公平的。但是,由于 ABI 兼容性的需要,我们一直坚持这个限制。C++ 对于可变参数函数也有同样的问题。)
Variadic arguments must be the last argument. This is because a method in Objective-C is really just an ordinary C function in disguise, and C doesn't allow any arguments after a variadic argument either.
The reason C doesn't allow it has to do with the calling convention that C supports. When you call a variadic function, the number of variadic arguments is not actually known be the function at first. Different functions can then figure it out in different ways. In Objective C, terminating a variadic argument with
nil
is common. Theprintf
function figures out how many arguments it's passed based on the format string. Since the function doesn't initially know how many variadic arguments there are, it has no way of knowing the memory location of an argument after the variadic argument list.Look up "C calling conventions" if you wish to know more.
(Some consider this limitation to be a "wart" of the C language, which is fair. However, we are stuck with it due to the need for ABI compatibility. C++ has the same issue with variadic functions.)