当作为参数传递给Objective-C中的方法时迭代va_列表

当作为参数传递给Objective-C中的方法时迭代va_列表,objective-c,variadic-functions,Objective C,Variadic Functions,我想将变量参数列表从一个方法(functionOne)传递到另一个方法(functionTwo)。一切正常,只是我还没有弄清楚如何在functionTwo中设置va_列表,以便访问va_列表中的第一个参数。使用va_arg前进到va_列表中的第二个参数。Thx - (void)functionOne:(NSString *)configFiles, ... { va_list args; va_start(args, configFiles); [self functio

我想将变量参数列表从一个方法(functionOne)传递到另一个方法(functionTwo)。一切正常,只是我还没有弄清楚如何在functionTwo中设置va_列表,以便访问va_列表中的第一个参数。使用va_arg前进到va_列表中的第二个参数。Thx

- (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 *))) {
        ...
    }
}

第一个变量参数不是传递给
va_start
的参数,而是紧跟其后的参数。如果希望
functionTwo:
能够访问
configFiles
字符串,则需要显式地将其传入。

请参阅

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

请记住,Objective-C方法的实现只是 一段代码,如C函数。可变参数宏 在标准(3)手册页面中描述了以相同的方式工作的方法 就像它们在普通函数中所做的那样

这是一个Objective-C类别的示例,包含一个变量 方法,该方法在以零结尾的对象列表中追加所有对象 NSMutableArray实例的参数:

#导入
@接口NSMutableArray(variadicMethodExample)
//此方法接受以零结尾的对象列表。
-(void)appendObjects:(id)firstObject。。。;
@结束
@NSMutableArray的实现(variadicMethodExample)
-(void)appendObjects:(id)firstObject。。。{
每个项目的id;
va_列表参数列表;
if(firstObject)//第一个参数不是varargs列表的一部分,
{//所以我们将分别处理。
[自添加对象:第一个对象];
//开始扫描firstObject之后的参数。
va_开始(argumentList,firstObject);
while(eachObject=va_arg(argumentList,id))//尽可能多地获取类型为“id”的参数
[self addObject:eachObject];//这不是零,请将其添加到self的内容中。
va_end(论点列表);
}
}
@结束

我用于调试目的的解决方案如下

-(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);


}
-(void)调试:(NSString*)格式。。。{
if(level1){
funcCaller=[syms objectAtIndex:1];
}
NSString*logMessage=[NSString stringWithFormat:@“%@调试:%@”,funcCaller,logString];
NSLog(@“%@”,logMessage);
}

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

请注意,面向对象编程语言(如Objective-C)中的
函数被称为
方法
@HAS:ObjC中既有函数也有方法。问题中的过程确实是方法,但这并不意味着函数不存在。@Josh Caswell谢谢您的更正。我知道我们也可以在Objective-c中使用普通的旧c函数(没有Objective-c-only函数,是吗?)。我的评论确实不正确,我不知道为什么我会这样写。。。再次感谢:)@HAS:没问题;我经常自己写评论,后来我看到了,我想知道我是怎么想的,这些评论的措辞如此奇怪。是的,很抱歉出现了术语错误。草率的帖子。我将留下它,因为已经提供了一个很好的答案,它引用了原始帖子中的代码。我在QA1405中也看到了该代码示例,但我认为它是无效的。它似乎假设
va_arg
在完成时返回
nil
,但它没有。
va_arg
文档说,“如果没有下一个参数,或者如果类型与实际下一个参数的类型不兼容(根据默认参数升级),将发生随机错误。”@Rob据我所知,如果列表以零结尾,它将起作用。
-(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);


}