Reputation: 18816
I have a property self.shareURL
that may or may not be nil
and I'd like to wrap it in array. Obviously, if it's nil
I can't do that, so I'd like to have an empty array in that case. So I can write:
NSArray *items = [self shareURL] ? @[[self shareURL]] : @[];
However, I can construct it in one call to shareURL
, like this:
NSArray *items = [NSArray arrayWithObjects:[self shareURL], nil];
This works because arrayWithObjects:
will stop anyway once it sees the first nil
and the stack is not corrupted because Objective-C ABI doesn't require it to clear the varargs in the stack.
Is it ok to use the second form? Or is the first one more clear?
Upvotes: 0
Views: 1406
Reputation: 18816
Ok, for the record, I actually went with
NSMutableArray *items = [NSMutableArray new];
if (self.shareURL) {
[items addObject: self.shareURL];
}
as it makes more clear that there is a "default" state of empty array, and we try to add one object.
Upvotes: 0
Reputation: 3482
Both ways are OK, and the first one you can write like this:
NSArray *items = [self shareURL] ? : @[];
This is right.
NSArray *items = [self shareURL] ? @[[self shareURL]] : @[];
Upvotes: 0
Reputation: 150655
Rather than terseness, I would opt for readability:
NSArray *items = nil;
if ([self shareURL]) {
items = @[[self shareURL]];
} else {
items = @[];
}
Upvotes: 1
Reputation: 20410
Both options seem ok, but if you are asking for which one is more clear, I'd go for this one:
NSArray *items = [self shareURL] ? @[[self shareURL]] : @[];
Why? Because you are implementing the behaviour you want to achieve in that line, not as a consequence of something happening on the stack like on the second approach. In other words, you are achieving the behaviour you are specifying in the line.
If I'm a developer and I see that code, with the 1st approach I'll understand the behaviour, without any explanation.
Upvotes: 2