3

我在一个库中的方法,看起来像这样的objc方法:如何将数组传递给需要变参(如...')

- (id)initWithSomeObjects:(NSString *)something, ... NS_REQUIRES_NIL_TERMINATION; 

我真的很喜欢叫它用一个数组而不是var args,因为我想要传递的对象的数量是可以改变的。

有没有办法,使用performSelector或NSInvocation或objc_msgSend或其他什么,我可以调用var args方法,参数来自数组?

+0

我在这里找到了一种方法,但它不能在xcode4 +下编译 - http://www.cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html – Chris

+0

什么是编译错误? – Wain

+2

该程序不会做你想做的。这是将'NSArray'的内容传递给'va_list'。你的方法不需要'va_list',它需要可变数目的参数。一个'va_list'是它自己的类型 - 只是一个字节缓冲区,但它是一个单独的参数。你的方法看起来像' - (id)initWithSomeObjects:(va_list)objs'比较' - [NSString initWithFormat:]'和' - [NSString initWithFormat:arguments:]'。 –

回答

5

有没有简单的方法来做到这一点,因为如何传递参数进入特定系统的调用ABI的丑陋的细节,你必须知道例如有多少参数被放入寄存器,以及如何处理剩余的参数等。这将涉及汇编,并且不能以一般方式完成。

通常,其具有可变参数需要像这样,也将或者

  1. 提供另一种采用一个va_list参数,而不是(例如-[NSString initWithFormat:]具有-[NSString initWithFormat:arguments:])方法的方法或功能的任何API。如果是这种情况,那么您可以使用该技巧从您链接到的评论文章中构建va_list。 (即使构建的va_list是系统特定且不可移植的,但至少它可以在Mac和iPhone上工作,并且它相当简单,并且不涉及汇编。)
  2. 提供另一种方法,它需要一个NSArray *或一个C数组的元素(例如-[NSArray initWithObjects:]-[NSArray initWithObjects:count:]
  3. 有方法逐个添加元素,使得总体效果与将它们一起传递给可变参量方法相同(例如,可以实现-[UIAlertView initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:]末尾的可变长按钮标题通过多次呼叫-[UIAlertView addButtonWithTitle:])。

如果你有一个可变varargs API没有上述的API之一,那么这是一个糟糕的API设计,你应该抱怨谁写的。如果你真的遇到这种情况,我猜测可能会使用像libffi这样的东西,它允许你动态地调用函数,并且处理依赖于系统的调用机制的基本特性。

相关问题