Есть ли способ передать NSArray методу, который ожидает переменное количество аргументов, например + stringWithFormat: - PullRequest
4 голосов
/ 27 марта 2009

Некоторый контекст: я пытаюсь очистить часть своего кода FMDB. В моей единственной таблице много столбцов, и метод в FMDB, который мне нужно использовать, - это метод, который ожидает переменное число аргументов, аналогично методу класса NSString +stringWithFormat:.

Пример:

[db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,
@"hi'", // look!  I put in a ', and I'm not escaping it!
[NSString stringWithFormat:@"number %d", i],
[NSNumber numberWithInt:i],
[NSDate date],
[NSNumber numberWithFloat:2.2f]];

Когда в таблице только 5 столбцов, это не так уж и плохо, но когда в столбце более 20 столбцов, он начинает становиться волосатым.

Я хотел бы создать словарь со всей информацией об абстракции БД и динамически создавать эти запросы. У меня вопрос ... Как в Objective-C я могу обмануть этот метод, ожидающий переменное число аргументов, и вместо этого, возможно, передать ему NSArray?

Информация, связанная с данной:

Как мне написать метод, который принимает переменное число аргументов, например NSString's + stringWithFormat:?

Ответы [ 4 ]

6 голосов
/ 27 марта 2009

(Редактировать: это работало в дни GCC. Это не под Clang с Xcode 4.6.)


Получите объекты в массиве в массив C, затем обработайте это как список varargs:

//The example input array
int i = 42;
NSArray *array = [NSArray arrayWithObjects:
    [NSString stringWithFormat:@"number %d", i],
    [NSNumber numberWithInt:i],
    [NSDate date],
    [NSNumber numberWithFloat:2.2f],
    nil];

//The example destination (using NSString so anyone can test this)
NSString *string = nil;

//The intermediary C array
NSObject **arrayObjects = malloc(sizeof(NSObject *) * [array count]);
if (arrayObjects) {
    //Fill out the C array.
    [array getObjects:arrayObjects];

    //Use the C array as a va_list.
    string = [[[NSString alloc] initWithFormat:@"%@ %@ %@ %@" arguments:(va_list)arrayObjects] autorelease];

    free(arrayObjects);
}

NSLog(@"string: %@", string);

Выход:

2009-03-26 20:10:07.128 NSArray-varargs[606:10b] string: number 42 42 2009-03-26 20:10:07 -0700 2.2

В вашем случае вы будете использовать метод -[FMDatabase executeUpdate:arguments:].

4 голосов
/ 27 марта 2009

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

1 голос
/ 27 марта 2009

Я думаю, что NSInvocation может делать то, что вы ищете.

Просто будьте осторожны при вызове setArgumentForIndex, потому что аргументы 0 и 1 неявные, которые заполняет Obj-C, где arg 2 - это первый "настоящий" аргумент, который вы передаете.

0 голосов
/ 27 марта 2009

Это может быть не тот пример, который вы ищете. Но в этом случае я бы поместил ваши строковые значения в массив, а затем использовал [theArray componentsJoinedByString: @ ","], чтобы превратить их в список аргументов sql.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...