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



我想传递一个变量参数列表从一个方法(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 *))) {
        ...
    }
}

第一个variadic参数不是传递给va_start的参数-它是紧随其后的参数。如果你想让functionTwo:访问configFiles字符串,你需要显式地传递它。

参见Technical Q&A QA1405: Objective-C方法中的变量参数。

接受可变参数的方法称为可变方法。

请记住,Objective-C方法的实现只是代码块,如C函数。可变参数宏在标准(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

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

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

}

这样做的副作用是,您必须在参数上添加一个保护,以确保它不是NULL。

相关内容

  • 没有找到相关文章

最新更新