对于大多数人来说,这可能显然很简单,但是请你举个例子来说明如何创建类似的方法(在Objective-C中)和C中的函数来创建像NSString
的{{1}这样的函数},或stringWithFormat:
。
提醒一下:
NSLog()
我想创建类似于[NSString stringWithFormat:@"example tekst %i %@ %.2f", 122, @"sth", 3.1415"];
NSLog(@"account ID %i email %@", accountID, email);
的方法NSString
,stringWithFormat:
。
答案 0 :(得分:118)
一般来说,这些被称为“可变函数”(或其方法)。
要创建此项,只需结束您的方法声明, ...
,如
- (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);
,或者如果你想要一个字符串; initWithFormat:arguments:
上的NSString *
。
另一方面,如果您不使用字符串,而是使用
+ (NSArray *)arrayWithObjects:(id)object, ... NS_REQUIRES_NIL_TERMINATION;
事情变得容易多了。
在这种情况下,不是vprintf
- 样式函数,而是使用循环遍历args
,假设你去了id,并像在任何循环中那样解析它们。
- (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列表是nil-terminated。
注意:为了完成这项工作,可能必须包含<stdarg.h>
;但是如果内存服务,这将包含在与NSLogv的连接中,这意味着它通过“Foundation.h”,因此也是“AppKit.h”和“Cocoa.h”,以及其他一些内容;所以这应该是开箱即用的。
答案 1 :(得分:20)
- (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);
}
如果要将变量参数传递给stringWithFormat:,请使用类似:
的内容NSString *s=[[[NSString alloc] initWithFormat:format arguments:args] autorelease];
答案 2 :(得分:8)
这里要提到的一件事是,第一个NSString参数在这里作为格式,另一个在变量参数中传递。对?因此,在进入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, @"");
}