Singleton中的NSAssert:为什么这段代码有效?

时间:2012-04-19 21:31:55

标签: objective-c singleton nsassert

我不理解在+alloc中使用NSAssert,因为从+alloc调用+sharedGameManager时,静态_sharedGameManager变量为nil }(所以NSAssert应该在第一次调用[self alloc] init]时停止执行...)

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

感谢您的回答

3 个答案:

答案 0 :(得分:3)

你是否认为NSAssert错误的方式?

NSAssert( _sharedGameManager==nil, @"Attempted to …");

如果_sharedGameManager 不是,则抛出异常。它断言表​​达式为TRUE,它表示“我断言必须是这种情况”,因此_sharedGameManager必须为nil,否则会引发异常。只有在您尝试创建此类的2个实例时才会发生这种情况。

答案 1 :(得分:0)

这看起来像几个胶片粘在一起; alloc是一个实例方法,而不是类方法(静态)。如果要执行单例类的初始化,请使用+(void)initialize

Objective-C运行时声称保证此类方法只执行一次,因此它是设置单例的有效机制。如需进一步阅读,请点击Mike Ash的blog post主题。

答案 2 :(得分:0)

通过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保证只运行一次,因此您的游戏管理器不会过度初始化。只要您不释放它,它就会保持活跃状态​​,并且会在程序结束时正确发布(因为它的static上下文)。