Implement selection on a singleton

I would like to have a singleton in my system, but instead of calling the callers through some sharedInstance method, I would like them to not know that they are using a singleton, in other words, I would like the callers to say :

MyClass *dontKnowItsASingleton = [[MyClass alloc] init]; 

To accomplish this, I tried to override alloc as follows:

 // MyClass.m static MyClass *_sharedInstance; + (id)alloc { if (!_sharedInstance) { _sharedInstance = [super alloc]; } return _sharedInstance; } 

My question is: is this normal? This seems to work, but I had never redefined alloc before. Also, if everything is in order, can I always use this technique, and not the dispatch_once method that I did? ...

 + (id)sharedInstance { static SnappyTV *_sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedInstance = [[self alloc] init]; }); return _sharedInstance; } 
+4
source share
3 answers

As mentioned in @ H2CO3, your method of switching to singlet production is acceptable, but not thread safe. A more traditional approach is to wrap your assignment and comparison in the @synchronized block, so access to multiple threads is reduced, however overriding +alloc is not the best way to implement an already shaky template.

+5
source

I think you should use the initialize method:

 + (void) initialize { _sharedInstance= [[self alloc]init]; } + (id)sharedInstance { return _sharedIntsance; } 
+1
source

In case others come to see, here is a solution that, I think, combines all the useful tips:

 + (id)alloc { @synchronized(self) { if (!_sharedInstance) { _sharedInstance = [super alloc]; } return _sharedInstance; } } - (id)init { @synchronized(self) { static BOOL init = NO; if (!init) { init = YES; self = [super init]; } } return self; } 

Thanks to @ H2CO3 for the thread safety issue, @CodaFi for the thread safety recipe and @Rob Mayoff for the dangers with init under the arc. The best and brightest today helped me!

+1
source

All Articles