目标C中线程安全初始化器的这两种实现之间的差异。

时间:2022-03-25 17:01:49

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

所以我有一个单例和Im试图理解这两个实现之间的区别:从功能上来说,我尝试用这两个实现运行代码,它们都可以工作

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

然而,我注意到在第一个实现中没有调用[self alloc],而是调用[super alloc]。我对此有点困惑。这似乎是可行的,但似乎有点神奇,所以我想知道是否有人可以澄清

1st way:

方式1:

 +(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;
 }

3 个解决方案

#1


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.

使用[self alloc] vs [super alloc]没有区别,除非类也重写+alloc。也就是说,它应该调用[self - alloc]。我打赌它会调用super,因为它可能是根据重写+alloc返回单例的实现而修改的。

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.

在任何情况下,除了self和super之外,这两种模式之间的区别在我对另一个问题的回答中得到了解释,但简而言之,dispatch_once()是实现这一目的的现代方法。它比@synchronized要快,并且包含了更多的语义。

#2


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).

就像在http://cocoasamurai.blogspot.fi1//2014/singleton—your-doing-them-wrong。在html中,dispatch_once调用看起来比@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.

至于为什么[super alloc]而不是[self alloc],我看不出为什么它会特别应用于dispatch_once版本,而不是另一个版本。在静态方法中,self简单地引用类本身(并且超级到它的直接超类),我将它看作是编写实际类名的缩写,仅此而已。

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.

我只使用过[self - alloc],因为无论如何,我已经写了当前类的名称,而不是它的超类。不知道具体调用[super alloc]是否有什么特殊意义。

#3


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.

在类方法中,self指向类本身。在您的两个实现中,[self alloc]、[MySingleton alloc]和[super alloc]在语义上都是相等的——除非您出于某种奇怪的原因重写+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:

您可能想要使用[super alloc]的一个原因是,当您在声明中显式地标记+alloc时,使用编译器指令:

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

+(instancetype) alloc __attribute__(unavailable(“alloc not available”));

or

+(instancetype) alloc NS_UNAVAILABLE;

+(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.

否则,当您试图+alloc您的单例类的实例时,编译器将会引发错误——这通常是您想要的,除非您在dispatch_once中+alloc一个共享单例实例。

#1


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.

使用[self alloc] vs [super alloc]没有区别,除非类也重写+alloc。也就是说,它应该调用[self - alloc]。我打赌它会调用super,因为它可能是根据重写+alloc返回单例的实现而修改的。

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.

在任何情况下,除了self和super之外,这两种模式之间的区别在我对另一个问题的回答中得到了解释,但简而言之,dispatch_once()是实现这一目的的现代方法。它比@synchronized要快,并且包含了更多的语义。

#2


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).

就像在http://cocoasamurai.blogspot.fi1//2014/singleton—your-doing-them-wrong。在html中,dispatch_once调用看起来比@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.

至于为什么[super alloc]而不是[self alloc],我看不出为什么它会特别应用于dispatch_once版本,而不是另一个版本。在静态方法中,self简单地引用类本身(并且超级到它的直接超类),我将它看作是编写实际类名的缩写,仅此而已。

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.

我只使用过[self - alloc],因为无论如何,我已经写了当前类的名称,而不是它的超类。不知道具体调用[super alloc]是否有什么特殊意义。

#3


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.

在类方法中,self指向类本身。在您的两个实现中,[self alloc]、[MySingleton alloc]和[super alloc]在语义上都是相等的——除非您出于某种奇怪的原因重写+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:

您可能想要使用[super alloc]的一个原因是,当您在声明中显式地标记+alloc时,使用编译器指令:

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

+(instancetype) alloc __attribute__(unavailable(“alloc not available”));

or

+(instancetype) alloc NS_UNAVAILABLE;

+(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.

否则,当您试图+alloc您的单例类的实例时,编译器将会引发错误——这通常是您想要的,除非您在dispatch_once中+alloc一个共享单例实例。