Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make yourself a method such as -[NSArray arrayWithObjects:]; infinite parameters separed by , ended by nil on argument

Tags:

objective-c

On Objective-C, I can do something like:

UIAlertView *av = [[UIAlertView alloc] initWith ... otherButtonTitles:@"button1", @"button2", nil];

Can I make a method for myself which takes as an argument these parameters separed by a comma... And if so how?

like image 438
Matoe Avatar asked Oct 08 '11 23:10

Matoe


People also ask

Should I terminate the list of objects with nil?

You should not terminate the list of objects with nil when using this literal syntax, and in fact nil is an invalid value. For more information about object literals in Objective-C, see Working with Objects in Programming with Objective-C.

How to create methods with infinite parameters?

c# - Creating methods with infinite parameters? - Stack Overflow Creating methods with infinite parameters? foo = string.Format (" {0} {1} {2} {3} ...", "aa", "bb", "cc" ...); This method Format () accepts infinite parameters, being the first one how the string should be formatted and the rest are values to be put in the string.

What is the arity of a method with multiple arguments?

If the method takes a fixed number of arguments, the arity will be a positive integer. If the method takes a variable number of arguments, the arity will be (-n-1) where n is the number of required arguments. Keyword arguments are counted as a single argument. Block is not considered as an argument.

How do I call a function that takes a params argument?

The code shows various things. First of all the argument with the params keyword must always be last (and there can be only one per function). Furthermore, you can call a function that takes a params argument in two ways. The first way is illustrated in the first line of MyFunction where each number is added as a single argument.


1 Answers

Declare the method like this in your @interface:

- (id)myObjectWithObjects:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION;

Then in the @implementation you would define it like this:

- (id)myObjectWithObjects:(id)firstObject, ...
{
    va_list args;
    va_start(args, firstObject);
    for (id arg = firstObject; arg != nil; arg = va_arg(args, id))
    {
        // Do something with the args here
    }
    va_end(args);

    // Do more stuff here...
}

The va_list, va_start, va_arg and va_end are all standard C syntax for handling variable arguments. To describe them simply:

  • va_list - A pointer to a list of variable arguments.
  • va_start - Initializes a va_list to point to the first argument after the argument specified.
  • va_arg - Fetches the next argument out of the list. You must specify the type of the argument (so that va_arg knows how many bytes to extract).
  • va_end - Releases any memory held by the va_list data structure.

Check out this article for a better explanation - Variable argument lists in Cocoa


See also: "IEEE Std 1003.1 stdarg.h"


Another example from the Apple Technical Q&A QA1405 - Variable arguments in Objective-C methods:

@interface NSMutableArray (variadicMethodExample)

- (void) appendObjects:(id) firstObject, ...; // This method takes a nil-terminated list of objects.

@end

@implementation NSMutableArray (variadicMethodExample)

- (void) appendObjects:(id) firstObject, ...
{
    id eachObject;
    va_list argumentList;
    if (firstObject) // The first argument isn't part of the varargs list,
    {                                   // so we'll handle it separately.
        [self addObject: firstObject];
        va_start(argumentList, firstObject); // Start scanning for arguments after firstObject.
        while (eachObject = va_arg(argumentList, id)) // As many times as we can get an argument of type "id"
            [self addObject: eachObject]; // that isn't nil, add it to self's contents.
        va_end(argumentList);
    }
}

@end
like image 91
chown Avatar answered Nov 15 '22 06:11

chown