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一个共享单例实例。