You are correct in thinking that if
block might cause problems. Here's why (source):
This line
[[MyHelper alloc] init];
is actually made up of three steps:
- Allocate memory
- Construct object into allocated memory
- Point static variable to the allocated memory address
Now, you would expect these things to happen in order from 1-3. But, in certain cases, compiler may reorder the instructions such that step 3 happens before step 2 -
sharedHelper = // Step 3
operator new(sizeof(MyHelper)); // Step 1
new (sharedHelper) MyHelper; // Step 2
Now, consider this scenario: Thread 1 executes steps 1 and 3 and is suspended. So the static variable points to a memory location that has not yet been initialized. Now, if thread 2 checks if(sharedHelper)
, it finds a non-NULL address, and returns that address. But wait, this address is not initialized yet - and BAM, you have a EXC_BAD_ACCESS.
Also check this related excellent answer.