如何在Objective-C中创build可变参数方法
也许这对大多数人来说显然是简单的,但是请你举个例子来说明如何创build类似的方法(在Objective-C中)和C中的函数来创build像NSString
的stringWithFormat:
或者NSLog()
只是提醒一下:
[NSString stringWithFormat:@"example tekst %i %@ %.2f",122,@"sth",3.1415"]; NSLog(@"account ID %i email %@",accountID,email);
我想创build类似于NSString
的方法stringWithFormat:
, NSURL - urlWithFormat
。
先谢谢你。
一般来说,这些被称为“可变参数函数”(或方法,因为它)。
要创build这个,只需结束你的方法声明, ...
,如
- (void)logMessage:(NSString *)message, ...;
在这一点上,你可能想把它包装在一个类似printf
的函数中,因为实现其中一个从头开始尝试。
- (void)logMessage:(NSString *)format, ... { va_list args; va_start(args, format); NSLogv(format, args); va_end(args); }
注意使用NSLogv
而不是NSLog
; 考虑NSLog(NSString *, ...);
vs NSLogv(NSString *, va_list);
,或者如果你想要一个string; initWithFormat:arguments:
在NSString *
。
另一方面,如果你不使用string,而是使用类似的东西
+ (NSArray *)arrayWithObjects:(id)object, ... NS_REQUIRES_NIL_TERMINATION;
事情变得更容易了。
在这种情况下,不要使用vprintf
风格的函数,而是使用一个循环遍历args
,假设id为你,并且像在任何循环中一样parsing它们。
- (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); }
当然,最后一个例子假设va_args列表没有被终止。
注意:为了使这个工作,你可能必须包括<stdarg.h>
; 但是如果内存服务,这将被包含在NSLogv中,这意味着它通过“Foundation.h”,因此还有“AppKit.h”和“Cocoa.h”以及其他一些内容。 所以这应该开箱即用。
- (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); }
如果你想将可变parameter passing给stringWithFormat:,请使用如下所示:
NSString *s=[[[NSString alloc] initWithFormat:format arguments:args] autorelease];
这里要提到的一点是,这里的第一个NSString参数是格式化的,另一个是在variables参数中传递的。 对? 所以在进入for循环之前,你需要一个参数来处理。
- (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, @""); }