I have data source method which asks for an NSArray
of numbers; some of them could be nil
, but I need to return every value anyways.
The method might look like this:
- (NSArray *)configurationValues:(Configuration *)configuration {
....
return [NSArray arrayWithObjects:value1, value2, value3, value4, nil];
}
If the value3
is nil
, I have to return {2, 3, (object is nil), 3}.
Off course I'm getting exceptions because I can't insert a nil
object.
What I can do is check every object and insert some dummy number or NSNull
, but this to me seems like boilerplate, and not really elegant.
I'm trying to create a category for NSArray
which would replace all nil
values with something else to avoid the exceptions:
@implementation NSArray (Nullable)
+ (instancetype)arrayWithObjectsSafe:(id)firstObj, ... {
NSMutableArray *array = [NSMutableArray array];
va_list args;
id object;
va_start(args, firstObj);
while((object = va_arg(args, id))) {
if (object) {
[array addObject:object];
} else {
// Insert dummy element // stuck here
[array addObject:[NSNull null]];
}
NSLog(@"OBJECT %@", object);
}
va_end(args);
return [NSArray arrayWithArray:array];
}
@end
I'm not really familiar with variadic methods, and I'm stuck here because the while
loop skips the nil
value, so the final array contains only the elements before the nil
.
Can I fix this, or is there an existing way for NSArray
to not throw an exception when trying to insert nil
object?
Your code fails simply because you are using nil
as both your end of arguments marker and as one of the arguments. Just use a different end of arguments marker. For example you can define:
const id END_MARKER (__bridge id)(void *)-1;
to define another constant rather like nil
(which has the value 0). Change your loop to:
while((object = va_arg(args, id)) != END_MARKER)
and your call to:
[NSArray arrayWithObjects:value1, value2, value3, value4, END_MARKER];
and your code works.
HTH