0

The code below is from the Big Nerd Ranch iOS programming book, 3rd edition. It's a class method that checks whether the singleton class BNRItemStore has been instantiated. If it has, it returns the singleton instance, and if it hasn't it creates it. The part I don't understand is the static variable. I know that static variables keep state, however, wouldn't calling the method a second time reset the *sharedStore back to nil? i.e. isn't this an assignment which would erase the creation of the singleton instance once the method was called again?

static BNRItemStore *sharedStore = nil; 

Method

+(BNRItemStore *)sharedStore { static BNRItemStore *sharedStore = nil; if (!sharedStore) sharedStore = [[ super allocWithZone:nil ] init ]; return sharedStore; } 
1
  • It's a weirdness of C's static implementation: Regardless of where the static variable is declared, any initialization that occurs in the declaration statement is only executed once. Commented Feb 22, 2014 at 19:48

3 Answers 3

2

Unfortunately, C terminology is really confusing. static has nothing to do with singletons, standing still, not changing, or anything like that. It has to do with the level at which storage takes place.

A variable declared inside a method/function is normally an automatic variable, meaning that it goes out of existence when the scope ends (i.e. execution reaches the end of the surrounding curly braces). A variable declared static, however, is stored at the level of the file that holds the code; once the file is loaded, this variable persists, even though it is declared inside a method/function.

Now we come to the question of how you will know whether this variable has ever been assigned a value, because you only want to assign it once. In theory, a static variable has a zero value when it is initially declared. Thus, if you said merely

 static BNRItemStore *sharedStore; 

...the code might work, because zero is nil for an instance, so we could test against nil and assign a value only in that case. However, it does no harm to make assurance double sure. Thus, we typically initialize the variable to nil when we declare it, just so we can be sure our nil test will work the first time.

That initializer, as you've already been told, will then take effect only once, because after that, the value persists and so the variable never needs to be initialized again (and never is).

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

1 Comment

One explanation is that the word "static" describes where in memory the variable is stored. A normal automatic variable gets stored in a different place in memory depending on where it is in the call stack automatically, but a static variable is always stored in the same place, so when it is accessed again in a different context it still contains the same value.
1

The code is fine, the initialiser only gets called the first time.

3 Comments

I think you misunderstood my question. I'm asking why the initializer wouldn't get called a second time. In other words, if I called sharedStore a second time, doesn't the static variable *sharedStore get set to nil, which would then mean there is no shared store so the code inside if(!sharedStore) gets run?
Is this more helpful? stackoverflow.com/questions/5567529/… This behaviour is the same in Objective C.
“the initializer only gets called the first time” Or more accurately, the initializer is “baked-in” at compile-time— so the initial value is part of the program's executable (like how const values work) and when the program is launched and the executable's memory layout is loaded onto the stack, the initial value is loaded alongside everything else that's static (static vars, consts, classes).
0

Static initializers are guaranteed by the language specification to only be executed one time, (and that's actually done at application start time, not as a part of function execution) so the static variable will only be nil the first time the function is executed.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.