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.

3 Answers 3

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];
}
Sign up to request clarification or add additional context in comments.

4 Comments

Is there also a way to take ellipsis as parameter and then pass is over to another method?
@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.
Can you give a code example with passing a ellipsis to a second objective-c method?
You can't actually pass the ellipsis. You have to pass the va_list. Example added.
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

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.