3

我在库中有一个方法,如下所示:

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

我真的很想用数组而不是 var args 来调用它,因为我想传入的对象数量是可变的。

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

4

1 回答 1

5

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

通常,任何具有采用此类可变参数的方法或函数的 API 也将

  1. 提供另一种采用va_list参数的方法(例如-[NSString initWithFormat:]has -[NSString initWithFormat:arguments:])。如果是这种情况,那么您可以使用该技术va_list从您在评论中链接到的文章中构建。(即使构建va_list是特定于系统且不可移植的。但至少它可以在 Mac 和 iPhone 上运行,而且操作相当简单且不涉及组装。)
  2. 提供另一种采用NSArray *元素或 C 数组的方法(例如-[NSArray initWithObjects:]has -[NSArray initWithObjects:count:]
  3. 有方法一个一个地添加元素,这样整体的效果就和把它们一起传给varargs方法一样(例如,通过多次-[UIAlertView initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:]调用可以实现末尾的varargs按钮标题)。-[UIAlertView addButtonWithTitle:]

如果你的可变参数 API 没有上述任何一种,那么它就是一个设计糟糕的 API,你应该向编写它的人投诉。如果你真的遇到这种情况,我猜可以使用 libffi 之类的东西,它允许你动态地进行函数调用,并处理依赖于系统的调用机制的细节。

于 2013-07-17T22:32:08.817 回答