Возможно, отправляют массив в Obj-c для функции аргументов переменной?

Ошибка, которую вы получаете, заключается в том, что файл открыт вами или кем-то еще на общем диске (вероятно, кем-то еще). Python не может получить блокировку файла. Измените имя файла и посмотрите, можете ли вы записать другой файл в том же месте.

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

12
задан Justin 12 June 2014 в 18:27
поделиться

6 ответов

К сожалению, нет. Objective C не имеет аргумента, распаковывающего как Вы, входят в большое количество современных языков. Нет даже хорошего способа работать вокруг этого, что я когда-либо находил.

Часть проблемы - то, что Objective C по существу просто C. Это делает несколько передача параметров с C varargs, и нет никакого простого способа сделать это с varargs. Соответствующее ТАК обсуждение.

15
ответ дан 2 December 2019 в 03:25
поделиться

Я хотел сделать то же самое. Я придумал следующее, которое хорошо работает, учитывая некоторые ограничения на входные переменные.

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;
4
ответ дан 2 December 2019 в 03:25
поделиться

Для выполнения, что Вы хотите необходимо использовать "varargs", как метод использует, или можно передать в массиве значений, чего-то как [db executeUpdate:sql withValues:vals];, и затем вытащите значения в методе. Но нет никакого способа сделать что-то больше "Pythonic", такой как автоматическая распаковка кортежа значений, а-ля def executeUpdate(sql, *args).

1
ответ дан 2 December 2019 в 03:25
поделиться

К сожалению (Цель-) 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);

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

1
ответ дан 2 December 2019 в 03:25
поделиться

Здесь есть хороший пример перехода от 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, но эй ...

3
ответ дан 2 December 2019 в 03:25
поделиться

Вам следует использовать новую версию FMDB http://github.com/ccgus/fmdb . У него есть нужный вам метод:

- (BOOL) executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments;
2
ответ дан 2 December 2019 в 03:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: