I'm getting a EXC_BAD_ACCESS when using va_args (iOS 7, Xcode 5.1.1, ARC on):
// ...
int val = sqlIntQuery(@"format_string", @"arg1"); // <-- does not work
int val = sqlIntQuery(@"format_string", @"arg1", nil); // <-- this works
// ...
- (int)sqlIntQuery:(NSString *)format, ...
{
va_list args;
va_start(args,format);
__unsafe_unretained id eachObject;
NSMutableArray *arguments = [NSMutableArray array];
while ( (eachObject = va_arg(args, id)) != nil ) { // <-- crash on 2nd loop
[arguments addObject:eachObject];
}
va_end(args);
// ... process 'arguments'
return 5; // return a computed intValue
}
If I put a "break;" at the end of the loop (because I only have one argument), or add "nil" as a last argument, there's no crash, but I don't think I should have to add the "nil". I suspect an ARC issue, but I'm using __unsafe_unretained, as suggested elsewhere on SO. (Is there a way I can push "nil" into to args?)
What's causing the failure on the second time through the loop?
EDIT Aug 6: My Solution:
The accepted solution by maddy pushed me in the right direction when he mentioned "the number of format specifiers." My format argument has a '?' placeholder for each argument, so I just count those. So, for the record:
- (int)sqlIntQuery:(NSString *)format, ...
{
int numberOfArgs = [format componentsSeparatedByString:@"?"].count - 1; // <<-- this solved my problem
va_list args;
va_start(args,format);
NSMutableArray *arguments = [NSMutableArray array];
while ( numberOfArgs-- ) {
id eachObject = va_arg(args, id);
[arguments addObject:eachObject];
}
va_end(args);
FMResultSet *rs = [db executeQuery:format withArgumentsInArray:arguments];
[rs next];
int ret = [rs intForColumnIndex:0];
[rs close];
return ret;
}
It's a double-wrapper. My routine is a wrapper around FMDB, which is itself a wrapper for SQLite.