Итак, мы пытаемся пройтись по примеру SQLite, который реализует NSFastEnumeration, предоставленный Lynda.com. Преобразование его в ARC было проблемой для меня, так как я не смог исправить ошибку
Cast of an indirect pointer to an Objective-C pointer to 'va_list' (aka char *) is disallowed with ARC.
Он указывает на эту линию и va_list
приведение
[self bindSQL:[query UTF8String] arguments:(va_list)values];
, которая находится в этой функции, где определено values
(__unsafe_unretained
было добавлено для исправления некоторых других ошибок)
- (NSNumber *) insertRow:(NSDictionary *) record
{
int dictSize = [record count];
__unsafe_unretained id values[dictSize];
Реализация bindSQL:
- (void) bindSQL:(const char *) cQuery arguments:(va_list)args
Как это исправить?
Спасибо за интерес, ребята. Как и было запрошено, исходная функция bindSQL и вызывающая функция insertRow
- (void) bindSQL:(const char *) cQuery arguments:(va_list)args {
// NSLog(@"%s: %s", __FUNCTION__, cQuery);
int param_count;
// preparing the query here allows SQLite to determine
// the number of required parameters
if (sqlite3_prepare_v2(database, cQuery, -1, &statement, NULL) != SQLITE_OK) {
NSLog(@"bindSQL: could not prepare statement (%s)", sqlite3_errmsg(database));
statement = NULL;
return;
}
if ((param_count = sqlite3_bind_parameter_count(statement))) {
for (int i = 0; i < param_count; i++) {
id o = va_arg(args, id);
// determine the type of the argument
if (o == nil) {
sqlite3_bind_null(statement, i + 1);
} else if ([o respondsToSelector:@selector(objCType)]) {
if (strchr("islISLB", *[o objCType])) { // integer
sqlite3_bind_int(statement, i + 1, [o intValue]);
} else if (strchr("fd", *[o objCType])) { // double
sqlite3_bind_double(statement, i + 1, [o doubleValue]);
} else { // unhandled types
NSLog(@"bindSQL: Unhandled objCType: %s", [o objCType]);
statement = NULL;
return;
}
} else if ([o respondsToSelector:@selector(UTF8String)]) { // string
sqlite3_bind_text(statement, i + 1, [o UTF8String], -1, SQLITE_TRANSIENT);
} else { // unhhandled type
NSLog(@"bindSQL: Unhandled parameter type: %@", [o class]);
statement = NULL;
return;
}
}
}
va_end(args);
return;
} * * тысяча двадцать-один
- (NSNumber *) insertRow:(NSDictionary *) record {
// NSLog(@"%s", __FUNCTION__);
int dictSize = [record count];
// the values array is used as the argument list for bindSQL
id keys[dictSize]; // not used, just a side-effect of getObjects:andKeys
id values[dictSize];
[record getObjects:values andKeys:keys]; // convenient for the C array
// construct the query
NSMutableArray * placeHoldersArray = [NSMutableArray arrayWithCapacity:dictSize];
for (int i = 0; i < dictSize; i++) // array of ? markers for placeholders in query
[placeHoldersArray addObject: [NSString stringWithString:@"?"]];
NSString * query = [NSString stringWithFormat:@"insert into %@ (%@) values (%@)",
tableName,
[[record allKeys] componentsJoinedByString:@","],
[placeHoldersArray componentsJoinedByString:@","]];
[self bindSQL:[query UTF8String] arguments:(va_list)values];
sqlite3_step(statement);
if(sqlite3_finalize(statement) == SQLITE_OK) {
return [self lastInsertId];
} else {
NSLog(@"doQuery: sqlite3_finalize failed (%s)", sqlite3_errmsg(database));
return [NSNumber numberWithInt:0];
}
}