How to create variable argument methods in Objective-C How to create variable argument methods in Objective-C xcode xcode

How to create variable argument methods in Objective-C


What these are called, generally, is "variadic functions" (or methods, as it were).

To create this, simply end your method declartion with , ..., as in

- (void)logMessage:(NSString *)message, ...;

At this point you probably want to wrap it in a printf-like function, as implementing one of those from scratch is trying, at best.

- (void)logMessage:(NSString *)format, ... {  va_list args;  va_start(args, format);  NSLogv(format, args);  va_end(args);}

Note the use of NSLogv and not NSLog; consider NSLog(NSString *, ...); vs NSLogv(NSString *, va_list);, or if you want a string; initWithFormat:arguments: on NSString *.


If, on the other hand, you are not working with strings, but rather something like

+ (NSArray *)arrayWithObjects:(id)object, ... NS_REQUIRES_NIL_TERMINATION;

things get a lot easier.

In that case, instead of a vprintf-style function, use a loop going through args, assuming id as you go, and parse them as you would in any loop.

- (void)logMessage:(NSString *)format, ... {  va_list args;  va_start(args, format);  id arg = nil;  while ((arg = va_arg(args,id))) {  /// Do your thing with arg here  }  va_end(args);}

This last sample, of course, assumes that the va_args list is nil-terminated.

Note: In order to make this work you might have to include <stdarg.h>; but if memory serves, this gets included in connection with NSLogv, meaning it comes down by way of "Foundation.h", therefore also "AppKit.h" and "Cocoa.h", as well as a number of others; so this should work out of the box.


- (void)methodWithFormat:(NSString*)format, ... {  va_list args;  va_start(args,format);  //loop, get every next arg by calling va_arg(args,<type>)  // e.g. NSString *arg=va_arg(args,NSString*) or int arg=(args,int)  va_end(args);}

If you want to pass the variable arguments to stringWithFormat:, use something like:

NSString *s=[[[NSString alloc] initWithFormat:format arguments:args] autorelease];


One thing to mention here is that, the first NSString parameter here comes as format, and the other are passed in the variable argument. right? So before entering the for loop, you have one parameter to handle.

- (NSString *) append:(NSString *)list, ...{    NSMutableString * res = [NSMutableString string];    [res appendString:list];    va_list args;    va_start(args, list);    id arg = nil;    while(( arg = va_arg(args, id))){        [res appendString:arg];    }    va_end(args);    return res;}- (void) test_va_arg{    NSString * t = [self append:@"a", @"b", @"c", nil];    STAssertEqualObjects(@"abc", t, @"");}