3

So I have a singleton and Im trying to understand the difference between these two implementations: functionally I have tried running my code with both of them and they both work

However, I notice that in the 1st implementation there is no [self alloc] being called instead the call is to [super alloc]. Im a bit perplexed by this. It seems to work but it seems a bit magical so Im wondering if someone can clarify

1st way:

 +(id)getSingleton
 {

    static dispatch_once_t pred;
    dispatch_once(&pred, ^{
    locMgrSingleton = [[super alloc] init];

        });

     return locMgrSingleton;

 }

Another way

 +(id)getSingleton
 {
     @synchronized(self)
     {
         if (locMgrSingleton == nil)
         {
             locMgrSingleton = [[self alloc]init];
             NSLog(@"Created a new locMgrSingleton");
         }
         else
        {
            NSLog(@"locMgrSingleton exists");
         }

     }

     return locMgrSingleton;
 }
banditKing
  • 9,405
  • 28
  • 100
  • 157
  • The first one should be using `self alloc`. – rmaddy Feb 14 '13 at 21:46
  • Are you asking about the differences in the synchronization mechanisms, or the difference between `[self alloc]` and `[super alloc]`? For the second, this may help: [Creating a singleton with allocWithZone:](http://stackoverflow.com/q/11962913) (assuming you've overridden `alloc`, anyways). – jscs Feb 14 '13 at 21:46

3 Answers3

4

Using [self alloc] vs [super alloc] makes no difference unless the class also overrides +alloc. That said, it should be calling [self alloc]. I'll bet it's calling super because this was probably adapted from an implementation that override +alloc to return a singleton.

In any case, the difference between the two patterns, besides self vs super, is explained in my answer to this other question, but in short, dispatch_once() is the modern way to do this. It's faster than @synchronized, and carries more semantic meaning.

Community
  • 1
  • 1
Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
1

As said on e.g. http://cocoasamurai.blogspot.fi/2011/04/singletons-your-doing-them-wrong.html, the dispatch_once call simply seems to be somewhat faster than @synchronized(self).

As to why [super alloc] instead of [self alloc], I don't see any reason why it would specifically apply to the dispatch_once version but not the other. In a static method, self simply refers to the class itself (and super to its direct superclass), and I'd see it as a shorthand for writing the actual class name, nothing more.

I've only ever used [self alloc] though, since I'd anyway otherwise written the name of the current class, not its superclass. No idea if specifically calling [super alloc] carries any special significance.

villapossu
  • 2,737
  • 4
  • 18
  • 19
1

In a class method, self points to the class itself. In both of your implementations, [self alloc], [MySingleton alloc] and [super alloc] are all semantically equivalent—unless you for some odd reason override +alloc.

One reason you might want to use [super alloc] over others is when you explicitly mark +alloc unavailable in your declaration with a compiler directive:

+(instancetype) alloc __attribute__((unavailable("alloc not available")));

or

+(instancetype) alloc NS_UNAVAILABLE;

Otherwise, compiler will raise an error when you try to +alloc an instance of your singleton class—and that's usually what you want except for when you +alloc a shared singleton instance in dispatch_once.

jmurzy
  • 3,816
  • 1
  • 17
  • 11