Why initialize static NSNumberFormatter to nil?


#1

I have a question about this chunk of code:

static NSNumberFormatter *currencyFormatter = nil; if (currencyFormatter == nil) { currencyFormatter = [[NSNumberFormatter alloc] init]; currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle; }

The point of making the NSNumberFormatter static is to avoid instantiating it more than once, right? So the code in the if block gets run the first time the method is executed, and then for every subsequent time it will simply reuse the same NSNumberFormatter object? In this case, doesn’t initializing it to nil negate that?

In other words, doesn’t initializing the pointer to nil then checking if it’s nil in the next line cancel itself out? Wouldn’t this if block just be run every time now?

Why isn’t it more like:

static NSNumberFormatter *currencyFormatter; if (currencyFormatter == nil) { currencyFormatter = [[NSNumberFormatter alloc] init]; currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle; }


#2

Actually two points. One as you noted, and the other to preserve its value from one method invocation to the next.

But here’s the trick. Think of a static variable declaration as exactly that: a declaration rather than an executable statement.

If you don’t specify an initial value, then it may (I don’t recall) start out with whatever was in that memory location – garbage.


#3

Hmm, ok… I think I get that aspect. But I still don’t see how the stuff in the if loop wouldn’t be triggered every time.

Isn’t it kind of like

int v = 1; if (v == 1) { doStuff(); }

Wouldn’t the doStuff() function be called every single time since the variable is set to the value that the if block is checking for right before the check?

So it’s different from my example because it’s a static variable? Or it’s different because it’s a pointer to an object?

I’m just not sure I understand how that if statement could ever not be satisfied.


#4

The answer is: the ‘if’ check returns NO every time after the first check.

Let’s trace through this one step at a time. Here’s the code again, for ease of reference:

    static NSNumberFormatter *currencyFormatter = nil;
    if (currencyFormatter == nil) {
        currencyFormatter = [[NSNumberFormatter alloc] init];
        currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
    }

The first time though, is currencyFormatter nil? The answer is: yes; it was initialized to nil, and it hasn’t changed since then.

So what does the body of the ‘if’ do? It changes currencyFormatter!!

Now the second time through, since currencyFormatter was declared static, the memory is still there, with the value that was last set – the formatter!

So is currencyFormatter nil now? The answer is: no! It wasn’t set to nil again because the static declaration is not an executable statement!

Thus, it differs from your example with non-static variable v in two ways:

  1. since v is not static, the memory is allocated (and initialized) each time it enters the method
  2. even if v was declared static, its value is not being changed in the body of the ‘if’

#5

Got it, great explanation.

Thank you very much!