Question

I have a method in a library that looks like so:

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

I'd really like to call it with an array instead of var args, because the number of objects i'd like to pass in is changeable.

Is there some way, using performSelector or NSInvocation or objc_msgSend or whatever, that i can call the var args method, with the arguments coming from an array?

Was it helpful?

Solution

There is no easy way to do this, because how arguments are passed goes into the ugly details of the particular system's calling ABI, and you have to know e.g. how many arguments are put into registers, and how to deal with remaining arguments, etc. And this will involve assembly and it cannot be done in a general way.

Generally, any API that has a method or function that takes varargs like this, also will either

  1. Provide another method that takes a va_list parameter instead (e.g. -[NSString initWithFormat:] has -[NSString initWithFormat:arguments:]). If this is the case, then you can use the technique to construct the va_list from the article you linked to in the comments. (Even constructing the va_list is system-specific and non-portable. But at least it works on Mac and iPhone and it's fairly simple to do and does not involve assembly.)
  2. Provide another method that takes an NSArray * or a C array of elements (e.g. -[NSArray initWithObjects:] has -[NSArray initWithObjects:count:])
  3. Have methods to add elements one by one such that the overall effect is the same as passing them all together to the varargs method (e.g. the varargs button titles at the end of -[UIAlertView initWithTitle:message:delegate:cancelButtonTitle:otherButtonTitles:] can be achieved by calling -[UIAlertView addButtonWithTitle:] multiple times).

If you have a varargs API that doesn't have one of the above, then it's a badly designed API and you should complain to whoever wrote it. If you really run into such a situation, I am guessing that it would be possible to use something like libffi, which allows you to make function calls dynamically, and handles the nitty gritty of system-dependent calling mechanisms.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top