Ошибка, которую вы получаете, заключается в том, что файл открыт вами или кем-то еще на общем диске (вероятно, кем-то еще). Python не может получить блокировку файла. Измените имя файла и посмотрите, можете ли вы записать другой файл в том же месте.
Запись на общие диски может быть сложной, так как блокировка файла может быть открыта в течение продолжительного периода времени, если человек, открывший файл, неправильно снимает блокировку с него.
К сожалению, нет. Objective C не имеет аргумента, распаковывающего как Вы, входят в большое количество современных языков. Нет даже хорошего способа работать вокруг этого, что я когда-либо находил.
Часть проблемы - то, что Objective C по существу просто C. Это делает несколько передача параметров с C varargs, и нет никакого простого способа сделать это с varargs. Соответствующее ТАК обсуждение.
Я хотел сделать то же самое. Я придумал следующее, которое хорошо работает, учитывая некоторые ограничения на входные переменные.
NSArray* VarArgs(va_list ap)
{
id obj;
NSMutableArray* array = [NSMutableArray array];
while ((obj = va_arg(ap, id))) {
[array addObject:obj];
}
return array;
}
#define VarArgs2(_last_) ({ \
va_list ap; \
va_start(ap, _last_); \
NSArray* __args = VarArgs(ap); \
va_end(ap); \
if (([__args count] == 1) && ([[__args objectAtIndex:0] isKindOfClass:[NSArray class]])) { \
__args = [__args objectAtIndex:0]; \
} \
__args; })
Используя вышеупомянутое, я могу назвать следующее или с NSArray или с varargs.
// '...' must be objc objects with nil sentinel OR an NSArray with nil sentinel
- (void)someMethod:(NSString *)sql, ...
{
NSArray *args = VarArgs2(sql);
// Do stuff with args
}
Еще одна подсказка должна использовать следующее в прототипе, чтобы иметь проверку компилятора на нулевую сигнальную метку для предотвращения потенциальных плохих вещей. Я вытащил это из заголовков яблока...
- (void)someMethod:(NSString *)sql, ... NS_REQUIRES_NIL_TERMINATION;
Для выполнения, что Вы хотите необходимо использовать "varargs", как метод использует, или можно передать в массиве значений, чего-то как [db executeUpdate:sql withValues:vals];
, и затем вытащите значения в методе. Но нет никакого способа сделать что-то больше "Pythonic", такой как автоматическая распаковка кортежа значений, а-ля def executeUpdate(sql, *args)
.
К сожалению (Цель-) C не позволяет делать это. executeUpdate метод должен был бы принять NSArray вместо списка аргумента переменной в этом случае.
Однако, если Вы действительно знаете объем записей в массиве (у Вас есть сумма в строке в примере так или иначе), можно, конечно, сделать что-то как
[db executeUpdate:@"insert into test (a, b) values (?, ?)", [values objectAtIndex:0], [values objectAtIndex:1]]
Если executeUpdate является внешним методом библиотеки, и та библиотека не предлагает версии метода, принимающего NSArray, Вы могли придумать свою собственную функцию обертки. Функция взяла бы строку запроса и массив как аргумент. Эта функция затем назвала бы executeUpdate метод с корректной суммой аргументов на основе длины массива, чего-то вроде
if ([values count] == 1) {
[db executeUpdate:query, [values objectAtIndex:0]];
}
else if ([values count] == 2) {
[db executeUpdate:query, [values objectAtIndex:0], [values objectAtIndex:1]];
}
Вы могли затем вызвать эту новую функцию как
executeUpdateWrapper(@"insert into test (a, b) values (?, ?)", values);
Очевидный недостаток в этом решении состоит в том, что необходимо обработать все возможные длины массива отдельно в функции, и это имеет много кода вставки копии.
Здесь есть хороший пример перехода от NSArray к va_list (см. Разделы «va_list в Какао» и «Создание поддельного va_list» внизу):
http: / /cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html
Вот тизер («аргументы» - это NSArray):
char *argList = (char *)malloc(sizeof(NSString *) * [arguments count]);
[arguments getObjects:(id *)argList];
contents = [[NSString alloc] initWithFormat:formatString arguments:argList];
free(argList);
Не совсем python или ruby, но эй ...
Вам следует использовать новую версию FMDB http://github.com/ccgus/fmdb . У него есть нужный вам метод:
- (BOOL) executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments;