帮助理解类方法返回单例 [英] Help understanding class method returning singleton
问题描述
有人可以帮助我理解以下方法是做什么的?
Can someone please help me understand what the following method is doing?
+ (Game *) shared
{
static Game *sharedSingleton;
@synchronized(self)
{
if (!sharedSingleton)
{
sharedSingleton = [[Game alloc] init];
}
}
return sharedSingleton;
}
推荐答案
显然, singleton是只创建一个实例。实现这个的第一步是通过 static Game * sharedSingleton;
来声明类的静态实例。
Obviously, the idea behind a singleton is to create only a single instance. The first step in achieving this is to declare a static instance of the class via the line static Game *sharedSingleton;
.
第二步是检查单个实例是否已经创建,如果不是,则创建它,如果是,则返回现有的单个实例。然而,第二个步骤打开了潜在的问题,在2个单独的线程尝试调用 + shared
方法在同一确切的时刻。你不会希望一个线程修改单个 sharedSingleton
变量,而另一个线程试图检查它,因为它可能会产生意想不到的结果。
The second step is to check whether the single instance is already created, and if it isn't, to create it, or if it is, to return the existing single instance. However, this second step opens up the potential for problems in the event that 2 separate threads try to call the +shared
method at the same exact moment. You wouldn't want one thread to be modifying the single sharedSingleton
variable while another thread is trying to examine it, as it could produce unexpected results.
这个问题的解决方案是使用 @synchronized()
编译器指令来同步访问括号之间指定的对象。例如,假设 Game
类的单个共享实例具有名为 players
的实例变量,它是一个 Player
类的实例的$ c> NSMutableArray 。让我们说 Game
类有一个 -addPlayer:
方法,它会修改 / code>实例变量添加指定的播放器。重要的是,如果该方法是从多个线程调用的,那么一次只允许一个线程修改
players
数组。所以,该方法的实现可能看起来像这样:
The solution to this problem is to use the @synchronized()
compiler directive to synchronize access to the object specified between the parenthesis. For example, say this single shared instance of the Game
class has an instance variable named players
which is an NSMutableArray
of instances of a Player
class. Let's say the Game
class had an -addPlayer:
method, which would modify the players
instance variable by adding the specified player. It's important that if that method were called from multiple threads, that only one thread be allowed to modify the players
array at a time. So, the implementation of that method might look something like this:
- (void)addPlayer:(Player *)player {
if (player == nil) return;
@synchronized(players) {
[players addObject:player];
}
}
使用 @synchronized )
指令确保只有一个线程可以一次访问玩家
变量。如果一个线程尝试,而另一个线程当前正在访问它,第一个线程必须等待,直到另一个线程完成。
Using the @synchronized()
directive makes sure only one thread can access the players
variable at a time. If one thread attempts to while another thread is currently accessing it, the first thread must wait until the other thread finishes.
虽然它更直接当你谈论实例变量,它可能不太清楚如何在类本身的单一创建方法中实现相同类型的结果。 @synchronized(self)
行中的 self
行基本上等同于 Game
类本身。通过在游戏
类上同步,它确保 sharedSingleton = [[Game alloc] init];
曾经叫过一次。
While it's more straightforward when you're talking about an instance variable, it's perhaps less clear how to achieve the same type of result within the single creation method of the class itself. The self
in the @synchronized(self)
line in the following code basically equates to the Game
class itself. By synchronizing on the Game
class, it assures that the sharedSingleton = [[Game alloc] init];
line is only ever called once.
+ (Game *) shared
{
static Game *sharedSingleton;
@synchronized(self) // assures only one thread can call [Game shared] at a time
{
if (!sharedSingleton)
{
sharedSingleton = [[Game alloc] init];
}
}
return sharedSingleton;
}
:已更新。基于我的测试一会儿(我现在刚刚重新测试),以下所有看起来是等效的:
: updated. Based on my tests a while back (and I just re-tested it now), the following all appear to be equivalent:
以外 @implementation
:
Game *sharedInstance;
@implementation Game
+ (Game *)sharedGame {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[[self class] alloc] init];
}
}
return sharedInstance;
}
@end
以外 @implementation
, static
:
static Game *sharedInstance;
@implementation Game
+ (Game *)sharedGame {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[[self class] alloc] init];
}
}
return sharedInstance;
}
@end
内部 @implementation
:
@implementation Game
static Game *sharedInstance;
+ (Game *)sharedGame {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[[self class] alloc] init];
}
}
return sharedInstance;
}
@end
内部 + sharedGame
:
@implementation Game
+ (Game *)sharedGame {
static Game *sharedInstance;
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[[self class] alloc] init];
}
}
return sharedInstance;
}
@end
唯一的区别是,没有 gdb 中的文件统计信息下不显示
static
关键字, sharedInstance
code>。显然,在最后一个变体中, sharedInstance
在 + sharedGame
方法之外不可见。但实际上,他们都确保当你调用 [Game sharedInstance]
时,你会得到 sharedInstance
sharedInstance
只创建一次。 (注意,需要进一步的预防措施来防止某人使用 Game * game = [[Game alloc] init];
)创建非singleton实例。
The only difference is that in the first variation, without the static
keyword, sharedInstance
doesn't show up under File Statics in gdb
. And obviously, in the last variation, sharedInstance
isn't visible outside of the +sharedGame
method. But practically speaking, they all assure that when you call [Game sharedInstance]
you'll get back the sharedInstance
, and that the sharedInstance
is only created once. (Note, however, that further precautions would be needed to prevent someone from creating a non-singleton instance using something like Game *game = [[Game alloc] init];
).
这篇关于帮助理解类方法返回单例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!