简体   繁体   中英

Is this method of initializing singleton thread safe?

this is a scope of code in our project, I think it is not thread-safe, because the scope

if(sharedHelper)
    return sharedHelper;

will cause problem, but I am not sure, could any one help me?

+(id) sharedHelper
{
static MyHelper *sharedHelper = nil;
static dispatch_once_t onceToken;

if(sharedHelper)
    return sharedHelper;

dispatch_once(&onceToken,^{

    sharedHelper = [[self alloc] init];
});

return sharedHelper;
}

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:

  1. Allocate memory
  2. Construct object into allocated memory
  3. 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM