1

I used to initialise variables before a conditional statement in the following way:

NSString *string = [[NSString alloc] init];
if (conditional statement) {
   string = @"foo";
}
else{
   string = @"bar";
}

But the Xcode Analyser complains:

"Value stored to 'string' during its initialization is never read"

So, I then tried a couple of different options:

A:

NSString *string = nil;
if (conditional statement) {
   string = @"foo";
}
else{
   string = @"bar";
}

B:

NSString *string = @"bar";
if (conditional statement) {
   string = @"foo";
}

So my question is, what is the best way to initialise a variable in objective c, before a conditional statement?

UPDATE:

The variable itself is not used [read] in the conditional. Here is an example below...

NSString *string = [[NSString alloc] init];
if (x == 0) {
   string = @"foo";
}
else{
   string = @"bar";
}

UPDATE:

Based on Sven's answer, it seems like a good compromise is:

NSString *string;
if (x == 0) {
  string = @"foo";
}
else{
  string = @"bar";
}
Charles Robertson
  • 1,760
  • 16
  • 21
  • Give some information about the conditional statement. Are you going to use string in the conditional statement. – Balagurubaran Jan 26 '17 at 21:00
  • Similar [question](http://stackoverflow.com/questions/13220777/objective-c-initializing-nsstring) or [is also good](http://stackoverflow.com/questions/9254502/nsstring-allocation-and-initializing) – Peter Jan 26 '17 at 21:02
  • @balagurubaran I have ammended the code to show that the variable is not read within the conditional itself. – Charles Robertson Jan 26 '17 at 21:49
  • @Peter The second link is about instance variables, but it is still quite useful. Thanks for your links... – Charles Robertson Jan 26 '17 at 22:00

1 Answers1

3

A and B are both valid options. In the end it won't really matter, if you just assign string literals. The compiler might even generate the same code for both cases.

Of course if you assign something other than compile-time constants you need to be more careful. Depending on the side effects that happen in your computation only one or the other version will be correct.

In your case A you won't even have to nil-initialise the variable at first, the compiler is smart enough to see that it is initialised in any case. For patterns like this where you want to initialise an variable depending on some conditions it's actually a good idea to skip the initialisation where the variable is defined. Then the compiler can produce a warning if there is a code path where you forgot to initialise the variable.

Another option for this is to use the ternary operator ?::

NSString *string = condition ? @"foo" : @"bar";

This is not just shorter to write, but also makes it immediately clear that the variable is initialised no matter what the condition is.

Sven
  • 22,475
  • 4
  • 52
  • 71
  • Thanks for the answer. Are you saying, I can just use something like this: NSString *string; rather than NSString *string = nil; – Charles Robertson Jan 26 '17 at 21:54
  • Thanks for the answer. Are you saying, I can just use something like this: NSString *string; rather than NSString *string = nil; If this is the case, I actually like NSString *string; the best. It is the cleanest solution, but I will need to check that the Analyser doesn't throw a wobbly... – Charles Robertson Jan 26 '17 at 22:05
  • 1
    That's exactly what I'm saying. You don't have to initialise a variable on the same line you define it. You just need to make sure it is initialised before you use it. – Sven Jan 26 '17 at 22:34
  • Excellent. Can I just ask what the point of using [[alloc] init] is? It seems like the Analyser will complain, unless the variable is read from before it is overwritten... – Charles Robertson Jan 26 '17 at 22:51
  • One last thing. Am I right in saying the NSString *string = [[NSString alloc] init]; allocates memory, then initialises. And NSString *string = @"foo"; allocates memory, initialises & adds a value, all in one go? – Charles Robertson Jan 26 '17 at 22:56
  • 1
    That is correct. Simple declare the object: NSstring *string; and you are all set. The object will have nil content by default and it's ready to be assigned a value. – Alex Jan 26 '17 at 23:16