NSAssert in Singleton : why this code is valid?
-
01-06-2021 - |
Domanda
i don't understand the use of NSAssert in +alloc
, as when +alloc
is called from +sharedGameManager
, the static _sharedGameManager
variable is nil
(so NSAssert
should stop execution the first time [self alloc] init]
is called...)
+(GameManager*)sharedGameManager {
@synchronized([GameManager class])
{
if(!_sharedGameManager)
[[self alloc] init];
return _sharedGameManager;
}
return nil;
}
+(id)alloc
{
@synchronized ([GameManager class])
{
NSAssert(_sharedGameManager == nil,
@"Attempted to allocated a second instance of the Game Manager singleton");
_sharedGameManager = [super alloc];
return _sharedGameManager;
}
return nil;
}
Thanks for your answer
Soluzione
Are you thinking of NSAssert the wrong way round?
NSAssert( _sharedGameManager==nil, @"Attempted to …");
Will throw an Exception if _sharedGameManager is not nil. It Asserts that the expression is TRUE, it says "I assert that this must be the case", therefore _sharedGameManager
must be nil, or an exception is raised. This could only happen if you tried to create 2 instances of this Class.
Altri suggerimenti
This looks like a couple of snippets glued together; alloc is an instance method, not a class method (static). If you want to perform initialization of a singleton class, use +(void)initialize
The Objective-C runtime claims to guarantee this class method only gets executed once, so it is an effective mechanism for setting up a singleton. For further reading, hit up Mike Ash's blog post on the topic.
There's a better way to guarantee the behavior you want, through Grand Central Dispatch:
+ (GameManager *)sharedGameManager {
static GameManager *sharedGameManager = nil;
static dispatch_once_t token;
dispatch_once(&token, ^{
sharedGameManager = [[GameManager alloc] init];
});
return sharedGameManager;
}
dispatch_once
is guaranteed to be run only once, so your game manager won't be over-initialized. As long as you don't release it, it will stay alive, and it will correctly be released at the end of your program (because of its static
context).