Вариадная функция без завершения nil

Я пытаюсь создать метод, подобный следующему:

- (void)setCondition:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);

Но так как я не очень хорошо разбираюсь в препроцессоре, я столкнулся с проблемой, которую я исправил в следующем фрагменте кода, но я хотел бы знать, нет ли более чистого способа достичь того, что я хочу, который должен остановиться после предоставленных аргументов

+ (CRCondition *)conditionWithFormat:(NSString *)format,... {
CRCondition *condition      = [[CRCondition alloc] init];

NSArray *conditionSliced    = [condition sliceFormatOperationFromString:format];

condition->_leftOperand     = [[conditionSliced objectAtIndex:0] retain];
condition->_operator        = [condition operatorFromString:[conditionSliced objectAtIndex:1]];
condition->_rightOperand    = [[conditionSliced objectAtIndex:2] retain];

id eachObject;
va_list argumentList;

va_start(argumentList, format);
while ((eachObject = va_arg(argumentList, id))) {
    if ([condition->_leftOperand isEqualToString:@"%K"]) {

        [condition->_leftOperand release];

        if ([eachObject isKindOfClass:[NSString class]])
            condition->_leftOperand = [eachObject retain];

        else
            condition->_leftOperand = [[eachObject description] retain];
    }

    else if ([condition->_rightOperand isKindOfClass:[NSString class]] &&
             [condition->_rightOperand isEqualToString:@"%@"]) {

        [condition->_rightOperand release];
        condition->_rightOperand = [eachObject retain];
    }

    else
        break;
}
va_end(argumentList);

if (![condition isOperatorValid]) {
    NSException *exception = [NSException exceptionWithName:@"Invalid Condition Operator" 
                                                     reason:@"The operator passed is invalid. Must follow the following regex pattern: ([(=><)|(A-Z)]{1,2})" 
                                                   userInfo:nil];
    [exception raise];
}

return [condition autorelease];

}

Проблема заключается в цикле while, который вращается и проходит мимо предоставленных аргументов (я знаю, почему он предоставляет мне другое значение, аргументы cmd и т. Д.)

Если вам нужно больше объяснений, пожалуйста, добавьте комментарии, чтобы я мог вернуться к вам.


person Pier-Olivier Thibault    schedule 14.05.2011    source источник


Ответы (1)


Обычный подход заключается в том, чтобы сначала проанализировать строку формата и выяснить, сколько аргументов должно следовать за ней на основе этого (обычно для любой строки формата существует ровно одно допустимое количество аргументов). Если количество аргументов невозможно вывести из строки формата, обычно список заканчивается nil (как в arrayWithObjects:...).

person omz    schedule 15.05.2011
comment
Первый подход, который вы упомянули, - это именно то, что я делаю прямо сейчас (см. код выше). Завершение nil полезно, когда вы создаете массивы, но совершенно бессмысленно, когда делаете что-то с использованием строки формата (как в stringWithFormat:... - person Pier-Olivier Thibault; 16.05.2011
comment
Может быть, я что-то упускаю, но кажется, что вы перебираете все заданные аргументы вместо того, чтобы останавливаться после того, как увидели все аргументы, указанные в строке формата. - person omz; 16.05.2011
comment
Фактически метод NSArray *conditionSliced = [condition sliceFormatOperationFromString:format];выводит CRCondition из формата. Затем я перебираю аргументы до тех пор, пока у меня не будет аргументов для передачи или я не нажму breakinstruction, если она не подходит для _leftOperand и _rightOperand - person Pier-Olivier Thibault; 18.05.2011