当作为参数传递给Objective-C中的方法时,迭代va_list

时间:2013-04-22 06:56:27

标签: objective-c variadic-functions

我想将一个变量参数列表从一个方法(functionOne)传递给另一个方法(functionTwo)。一切正常,除了我无法弄清楚如何在functionTwo中设置va_list,我可以访问va_list中的第一个参数。使用va_arg前进到va_list中的第二个参数。谢谢。

- (void)functionOne:(NSString *)configFiles, ... {
    va_list args;
    va_start(args, configFiles);
    [self functionTwo:args];
    va_end(args);
}

- (void)functionTwo:(va_list)files {
    NSString *file;
    while ((file = va_arg(configFiles, NSString *))) {
        ...
    }
}

3 个答案:

答案 0 :(得分:4)

第一个可变参数参数不是传递给va_start的参数 - 它就是紧随其后的参数。如果您希望functionTwo:能够访问configFiles字符串,则需要明确传递它。

答案 1 :(得分:2)

请参阅Technical Q&A QA1405: Variable arguments in Objective-C methods

  

采用可变参数的方法称为可变方法。

     

请记住,Objective-C方法的实现恰到好处   一个代码块,就像一个C函数。可变参数宏   stdarg(3)手册页中描述的方法在方法中的工作方式相同   正如他们在普通的功能中所做的那样。

     

以下是Objective-C类别的示例,其中包含可变参数   将所有对象附加到以nil结尾的列表中的方法   NSMutableArray实例的参数:

#import <Cocoa/Cocoa.h>

@interface NSMutableArray (variadicMethodExample)

// This method takes a nil-terminated list of objects.
- (void)appendObjects:(id)firstObject, ...;

@end

@implementation NSMutableArray (variadicMethodExample)

- (void)appendObjects:(id)firstObject, ... {
    id eachObject;
    va_list argumentList;
    if (firstObject) // The first argument isn't part of the varargs list,
        {                                   // so we'll handle it separately.
      [self addObject: firstObject];
      // Start scanning for arguments after firstObject.
      va_start(argumentList, firstObject);
      while (eachObject = va_arg(argumentList, id)) // As many times as we can get an argument of type "id"
      [self addObject: eachObject]; // that isn't nil, add it to self's contents.
      va_end(argumentList);
    }
}

@end

答案 2 :(得分:2)

我用于调试目的的解决方案就像

-(void) debug:(NSString*)format, ... {

    if (level < MXMLogLevelDebug) return;

    if(format == nil) return;

    va_list args, args_copy;
    va_start(args, format);
    va_copy(args_copy, args);
    va_end(args);

    NSString *logString = [[NSString alloc] initWithFormat:format
                                                  arguments:args_copy];

    NSString *funcCaller = @"";
    NSArray *syms = [NSThread  callStackSymbols];
    if ([syms count] > 1) {
        funcCaller = [syms objectAtIndex:1];
    }
    NSString *logMessage = [NSString stringWithFormat:@"%@ DEBUG: %@", funcCaller, logString];

    NSLog(@"%@",logMessage);


}

这可能产生的副作用是你必须在args上添加一个保护,以确保不是NULL。