7

Hee

Does anybody know how to implement an method in objective c that will take an array of arguments as parameter such as:

[NSArray arrayWithObjects:@"A",@"B",nil];

The method declaration for this method is:

+ (id)arrayWithObjects:(id)firstObj...

I can't seem to make such method on my own. I did the following:

+ (void) doSometing:(id)string manyTimes:(NSInteger)numberOfTimes;

[SomeClass doSometing:@"A",@"B",nil manyTimes:2];

It will give the warningtoo many arguments to function 'doSometing:manyTimes:'

Thanks already.

Mats Stijlaart
  • 5,058
  • 7
  • 42
  • 58

3 Answers3

12

The ellipsis (...) is inherited from C; you can use it only as the final argument in a call (and you've missed out the relevant comma in your example). So in your case you'd probably want:

+ (void)doSomethingToObjects:(id)firstObject, ...;

or, if you want the count to be explicit and can think of a way of phrasing it well:

+ (void)doManyTimes:(NSInteger)numberOfTimes somethingToObjects:(id)firstObject, ...;

You can then use the normal C methods for dealing with ellipses, which reside in stdarg.h. There's a quick documentation of those here, example usage would be:

+ (void)doSomethingToObjects:(id)firstObject, ...
{
    id object;
    va_list argumentList;

    va_start(argumentList, firstObject);
    object = firstObject;

    while(1)
    {
        if(!object) break; // we're using 'nil' as a list terminator

        [self doSomethingToObject:object];
        object = va_arg(argumentList, id);
    }

    va_end(argumentList);
}

EDIT: additions, in response to comments. You can't pass the various things handed to you in an ellipsis to another function that takes an ellipsis due to the way that C handles function calling (which is inherited by Objective-C, albeit not obviously so). Instead you tend to pass the va_list. E.g.

+ (NSString *)doThis:(SEL)selector makeStringOfThat:(NSString *)format, ...
{
    // do this
    [self performSelector:selector];

    // make string of that...

    // get the argument list
    va_list argumentList;
    va_start(argumentList, format);

    // pass it verbatim to a suitable method provided by NSString
    NSString *string = [[NSString alloc] initWithFormat:format arguments:argumentList];

    // clean up
    va_end(argumentList);

    // and return, as per the synthetic example
    return [string autorelease];
}
Huibin Zhang
  • 1,072
  • 1
  • 15
  • 30
Tommy
  • 99,986
  • 12
  • 185
  • 204
  • Is there also a way to take ellipsis as parameter and then pass is over to another method? – Mats Stijlaart Mar 11 '11 at 09:45
  • 1
    @Mats: you normally get the va_list and pass that on (hence, e.g. vprintf, or NSString -initWithFormat:arguments:). You can't just pass on whatever is described by the ellipsis (as in, have an ellipsis function call another) since the C runtime isn't required to know how much stuff is there and therefore can't copy it. – Tommy Mar 11 '11 at 12:11
  • Can you give a code example with passing a ellipsis to a second objective-c method? – Mats Stijlaart Mar 14 '11 at 12:17
  • You can't actually pass the ellipsis. You have to pass the va_list. Example added. – Tommy Mar 14 '11 at 13:06
4

Multiple arguments (also known as an arglist) can only come at the end of a method declaration. Your doSomething method would look something like this:

+ (void)doNumberOfTimes:(NSInteger)numberOfTimes withStrings:(id)firstArg, ...
{
    va_list args;
    va_start(args, firstArg);

    NSString * argString = firstArg;
    while (argString != nil)
    {
        // do something with argString here

        argString = va_arg(args, NSString *);
    }

    va_end(args);
}

To be called as follows:

[SomeClass doNumberOfTimes:2 withStrings:@"A", @"B", nil];

See also: How to create variable argument methods in Objective-C

Community
  • 1
  • 1
e.James
  • 116,942
  • 41
  • 177
  • 214
2

I think you're after a variadic function. Here's Apple's documentation: http://developer.apple.com/library/mac/qa/qa2005/qa1405.html

Mason
  • 3,577
  • 2
  • 20
  • 11