2013-04-22 3 views
3

Я хотел бы передать список аргументов переменных из одного метода (functionOne) в другой (functionTwo). Все работает отлично, за исключением того, что мне не удалось выяснить, как настроить va_list в функцииTwo таким образом, чтобы я мог получить доступ к первому параметру в va_list. Использование va_arg продвигается ко второму параметру в va_list. Спасибо.Итерация va_list при передаче в качестве параметра метода в Objective-C

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

Обратите внимание, что 'функции' в объектно-ориентированных языках программирования (например, Objective-C) называются' методами'! – HAS

+2

@HAS: В ObjC есть _both_ функции _and_ methods. Процедуры в вопросе действительно являются методами, но это не означает, что функции не существуют. –

+1

@JoshCaswell Спасибо за исправление. Я знал, что мы можем использовать простые старые c-функции в Objective-C (нет функций Objective-C-only, есть?). Мой комментарий действительно неправильный, я не знаю, почему я написал его вот так ... спасибо еще раз :) – HAS

ответ

4

Первый VARIADIC аргумент не аргумент, передаваемый va_start - это один сразу же после него. Если вы хотите, чтобы functionTwo: имел доступ к строке configFiles, вам необходимо передать ее в явном виде.

+0

Не то, на что я надеялся, но спасибо за ваш ответ. – Dan

2

См. Technical Q&A QA1405: Variable arguments in Objective-C methods.

Методы, которые принимают переменные аргументы, известны как вариационные методы.

Имейте в виду, что реализация метода Objective-C - это всего лишь блок кода, как функция C. Макросы с переменным аргументом , описанные в справочной странице stdarg (3), работают одинаково в методе , как и в обычной функции.

Вот пример категории Objective-C, содержащий VARIADIC метод, который присоединяет все объекты в ноль с концевыми список аргументов к экземпляру 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 
+1

Я тоже видел этот образец кода в QA1405, но я не думаю, что он действителен. Кажется, что 'va_arg' возвращает' nil', когда это делается, но это не так. В документации 'va_arg' говорится:« Если не существует следующего аргумента или тип несовместим с типом фактического следующего аргумента (в соответствии с продвижением по умолчанию), будут возникать случайные ошибки ». – Rob

+0

@Rob, как я понимаю, он будет работать, если список будет завершен в ноль. – Stefan

1

решение, которое Я использую для отладки, как

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


} 

побочный эффект, что это может быть в том, что вы должны добавить охранника на аргументах, чтобы убедиться, не NUL L.

Смежные вопросы