Suppose you want to write a function similar to NSLog, but which also stores the message in an array in addition to registering it. How do you implement this?
If you write the variation function void MySpecialLog(NSString *format, ...) , someone can call your function the same way as NSLog - MySpecialLog(@"Hello %@!", name); , but the only way to access additional arguments outside of format is a va_list . There is no splat operator in C or Obj-C allowing you to pass them directly to NSLog inside a function.
NSLogv solves this problem by simultaneously accepting all additional arguments through va_list . Its signature is void NSLogv(NSString *format, va_list args) . You can use it to create your own NSLog wrappers.
Obj-c
void MySpecialLog(NSString *format, ...) NS_FORMAT_FUNCTION(1, 2)
You can use the same method to port the NSLog using the Obj-C method. (And since -[NSString initWithFormat:] has a similar option called -initWithFormat:arguments: you can wrap it too.)
- (void)log:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2) { // Similarly to the above, we can pass all the arguments to -initWithFormat:arguments:. va_list args; va_start(args, format); NSString *message = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); // Why not both? va_start(args, format); NSLogv(format, args); va_end(args); }
Swift
In Swift, you can do this with a variational function that takes CVarArg... :
func mySpecialLog(_ format: String, _ args: CVarArg...) { withVaList(args) { NSLogv("You've called mySpecialLog()! " + format, $0) } }
source share