Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create variable argument methods in Objective-C

Maybe this will be obviously simple for most of you, but could you please give an example how to create similar methods (in Objective-C) and functions in C to create functions like NSString's stringWithFormat:, or NSLog().

Just to remind:

[NSString stringWithFormat:@"example tekst %i %@ %.2f", 122, @"sth", 3.1415"]; NSLog(@"account ID %i email %@", accountID, email); 

I'd like to create the similar to NSString's method stringWithFormat:, NSURL - urlWithFormat.

like image 417
Chris Rutkowski Avatar asked Jan 26 '11 12:01

Chris Rutkowski


Video Answer


1 Answers

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.

like image 136
Williham Totland Avatar answered Sep 22 '22 03:09

Williham Totland