某些上下文:我正在尝试清理一些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?
相关信息:
答案 0 :(得分:6)
(编辑:这在海湾合作委员会的日子里有效。从Xcode 4.6开始,它不属于Clang。)
将数组中的对象放入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:]
方法。
答案 1 :(得分:4)
在FMDatabase上创建一个带有数组并进行更新的类别可能更容易。您应该能够复制大部分executeUpdate来执行此操作。
答案 2 :(得分:1)
我认为NSInvocation可能会做你想要做的事情。
调用setArgumentForIndex时要小心,因为args 0和1是Obj-C填充的隐式,其中arg 2是你传递的第一个“真正的”arg。
答案 3 :(得分:0)
这可能不是您正在寻找的示例。但在这种情况下,我会将您的字符串值放入一个数组中,然后使用[theArray componentsJoinedByString:@“,”]将它们转换为您的sql参数列表。