In python it is easy to build a dictionary or array and pass it unpacked to a function with variable parameters
I have this:
- (BOOL) executeUpdate:(NSString*)sql, ... {
And the manual way is this:
[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]];
But I can't hardcode the parameters I'm calling, I want:
NSMutableArray *values = [NSMutableArray array];
for (NSString *fieldName in props) {
..
..
[values addObject : value]
}
[db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,??values];
Chuck is right, there's no proper argument unpacking in Objective-C. However, for methods that require nil termination (NS_REQUIRES_NIL_TERMINATION), you can expand the variable list larger than what is needed by using an array accessor that returns nil when index >= count
. This is most certainly a hack, but it works.
// Return nil when __INDEX__ is beyond the bounds of the array
#define NSArrayObjectMaybeNil(__ARRAY__, __INDEX__) ((__INDEX__ >= [__ARRAY__ count]) ? nil : [__ARRAY__ objectAtIndex:__INDEX__])
// Manually expand an array into an argument list
#define NSArrayToVariableArgumentsList(__ARRAYNAME__)\
NSArrayObjectMaybeNil(__ARRAYNAME__, 0),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 1),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 2),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 3),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 4),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 5),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 6),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 7),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 8),\
NSArrayObjectMaybeNil(__ARRAYNAME__, 9),\
nil
Now you can use NSArrayToVariableArgumentsList
wherever you expect a nil-terminated variable argument list (as long as your array is smaller than 10 elements). For example:
NSArray *otherButtonTitles = @[@"button1", @"button2", @"button3"];
UIActionSheet *actionSheet = [[self alloc] initWithTitle:@"Title"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:NSArrayToVariableArgumentsList(otherButtonTitles)];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With