How to create variable argument methods in Objective-C

This may be obvious to most of you, but could you give an example of how to create similar methods (in Objective-C) and C functions to create functions such as NSString stringWithFormat: or NSLog() .

Just a reminder:

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

I would like to create a similar method NSString stringWithFormat: NSURL - urlWithFormat .

+56
null objective-c format xcode variadic-functions
Jan 26 '11 at 12:41
source share
3 answers

What they are called, as a rule, is “variational functions” (or, as it were, methods).

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

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

At this point, you probably want to wrap it in a printf like function, since implementing one of them from scratch tries at best.

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

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




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

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

everything becomes much easier.

In this case, instead of using the vprintf -style function, use a loop that goes through args , assuming id as you go, and parse them like 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 example, of course, assumes that the va_args list is nil-terminated.

Note. . To do this, you may need to include <stdarg.h> ; but if the memory serves, this is included in the connection with NSLogv, that is, it happens with the help of "Foundation.h", therefore also "AppKit.h" and "Cocoa.h", as well as a number of others; therefore it should work out of the box.

+118
Jan 26 '11 at 12:56
source share
 - (void)methodWithFormat:(NSString*)format, ... { va_list args; va_start(args,format); //loop, get every next arg by calling va_arg(args,<type>) // eg NSString *arg=va_arg(args,NSString*) or int arg=(args,int) va_end(args); } 

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

 NSString *s=[[[NSString alloc] initWithFormat:format arguments:args] autorelease]; 
+19
Jan 26 '11 at 12:47
source share

It is worth mentioning here that the first NSString parameter is presented here as a format, and the other in the variable argument. right? Therefore, before entering the for loop, you have one parameter to process.

 - (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, @""); } 
+8
Feb 25 '14 at 12:25
source share



All Articles