Singleton pattern implementation

I saw this particular implementation of the singleton pattern everywhere:

+ (CargoBay *)sharedManager { static CargoBay *_sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedManager = [[CargoBay alloc] init]; }); return _sharedManager; } 

and it seems like it is considered good practice (in particular, it is CargoBay ).

The only part I don’t understand is the first line of static CargoBay *_sharedManager = nil; .

Why are you setting the static variable to nil ?

+4
source share
2 answers

It is simply a matter of readability, consensus and practice. This is really not necessary because:

One. Its value will never be tested. Older singleton implementations used to be famous

 + (id)sharedInstance { static SomeClass *shared = nil; if (shared == nil) shared = [[SomeClass alloc] init]; return shared; } 

code - for this method to work, the support variable must be initialized to nil, since if it weren’t the first time, it would falsely omit alloc-init in the if part and return a junk mail pointer, However, with the GCD solution, nil-check is no longer required - GCD processes the right button "execute this code only once".

Two. Nevertheless: static variables are implicitly initialized to zero. Therefore, even if you simply write static id shared; , will initially be nil .

Three. Why can this be good practice? Because, despite the first two reasons that I mentioned, it is even more readable to let the source code reader know that something is explicitly initialized to zero. Or even there may be some inappropriate implementations when the static variables are not automatically auto-initialized, and then this action must be taken.

+8
source

You set it to zero to make sure you get a clean instance.

This is a more readable version of what you want to do:

 + (GlobalVariables *)sharedInstance { // the instance of this class is stored here static GlobalVariables *myInstance = nil; // check to see if an instance already exists if (nil == myInstance) { myInstance = [[[self class] alloc] init]; } // return the instance of this class return myInstance; } 

But there are many messages that show how this could not be thread safe, so if you go to the hybrid of your method above and what I posted, you will get the following:

 // Declared outside Singleton Manager static SingletonClass *myInstance = nil; + (GlobalVariables *)sharedInstance { if (nil != myInstance) { return myInstance; } static dispatch_once_t pred; // Lock dispatch_once(&pred, ^{ // This code is called at most once per app myInstance = [[GlobalVariables alloc] init]; }); return myInstance; } 
+1
source

Source: https://habr.com/ru/post/1435669/


All Articles