如何在Objective-C中创建变量参数方法

时间:2011-01-26 12:41:12

标签: objective-c xcode format variadic-functions null

对于大多数人来说,这可能显然很简单,但是请你举个例子来说明如何创建类似的方法(在Objective-C中)和C中的函数来创建像NSString的{​​{1}这样的函数},或stringWithFormat:

提醒一下:

NSLog()

我想创建类似于[NSString stringWithFormat:@"example tekst %i %@ %.2f", 122, @"sth", 3.1415"]; NSLog(@"account ID %i email %@", accountID, email); 的方法NSStringstringWithFormat:

3 个答案:

答案 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, @"");
}