问题
I am trying to create a method like the following:
- (void)setCondition:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
But since I'm not great with preprocessor, I hit an issue that I have fixed in the following code snippet, but I'd like to know if there's not cleaner way to achieve what I want which is to stop after the provided arguments
+ (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];
}
The problem is with the while loop that circles and go past the provided arguments (I'm aware of why it's providing me other value, cmd args and such)
If you need any more explanation please add comments so I can get back to you.
回答1:
The usual approach would be to parse the format string first and figure out how many arguments should follow it based on that (there is usually exactly one valid number of arguments for any format string). If the number of arguments is not deducible from a format string, it is common to terminate the list with nil (as in arrayWithObjects:...
).
来源:https://stackoverflow.com/questions/6002969/variadic-function-without-nil-termination