0

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?

1
  • Yes, the second form should work. If you use it, however, be sure to comment the operation well, so you will understand what you're doing a year from now. Commented Nov 18, 2013 at 11:37

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Also the second one makes it look like the array will contain an object, which is something that could be tripped over in the future. i.e. you may assume that you can call objectAtIndex:0 and cause an exception, it won't be immediately obvious why the array is empty.
After some thought, yes, the intent is really not clear in the second example.
1

Rather than terseness, I would opt for readability:

NSArray *items = nil;
if ([self shareURL]) {
    items = @[[self shareURL]];
} else {
    items = @[];
}

1 Comment

I agree, and in fact I've decided to use something similar instead of either of one-liners.
0

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]] : @[];

2 Comments

No, it's -(NSURL *)shareURL, it doesn't return an array.
oh, it's my fault.It should be NSArray *items = [self shareURL] ? @[[self shareURL]] : @[];
0

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.

2 Comments

Except you've now changed your API to return a mutable array rather than an immutable one.
In this particular case (and this is why it's not strictly an answer to the question), items is a one-use array that is not stored, nor is it returned, so this doesn't seem to matter. I could also pass it with -copy if necessary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.