2012-04-19 2 views
2

私はシングルトンのNSAssert:なぜこのコードは有効ですか?

+(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; 
} 
(そう NSAssertは実行を最初 [self alloc] init]を停止する必要があります...と呼ばれている) +alloc+sharedGameManagerから呼び出されたときのように、静的 _sharedGameManager変数が nilで、 +allocでNSAssertの使用を理解していません

あなたのお返事ありがとう

答えて

3

あなたはNSAssertを間違った方法で考えていますか? _sharedGameManager nilでない場合

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

は例外をスローします。式がTRUEであると主張し、「これが当てはまると主張する」と言うので、_sharedGameManagerはnilでなければならず、例外が発生する。これは、このクラスのインスタンスを2つ作成しようとした場合にのみ発生します。

+0

オハイオ州のはい真、私はそれが反対だったと確信していた理由はありません:)答えのおかげで! – Paul

0

これは一緒に糊付けされたカップルのようです。 allocはクラスメソッド(静的)ではなくインスタンスメソッドです。シングルトンクラスの初期化を実行する場合は、+(void)initialize

Objective-Cランタイムの主張は、このクラスメソッドが1回だけ実行されることを保証するため、シングルトンを設定する有効なメカニズムです。さらに読むには、トピックのMike Ashのblog postを押してください。

+1

'+ alloc' _is_クラスメソッド。そうでなければ、あなたは正しい。ポールは2つの無関係な断片をまとめているようだ。誰もが実際には 'dispatch_once'を使ってシングルトンを作る必要があり、Appleが与えたパターンではありません。 –

+0

@wobbals:ありがとうwobbals、ヒントのおかげで、このコードを本で見つけましたが、このNSAssertについてどう思いますか?それは間違いですか?それはそれのように働くことができますか?もしそうなら、私はなぜ理解しません – Paul

+0

うーん、本当に2つの無関係なスニペットのようには見えない。どちらの方法も、お互いの存在下でしか動作することができませんでした。 – hooleyhoop

0

したい動作を保証するためのより良い方法は、グランドセントラル派遣を通じて、あります:

+ (GameManager *)sharedGameManager { 
    static GameManager *sharedGameManager = nil; 
    static dispatch_once_t token; 
    dispatch_once(&token, ^{ 
     sharedGameManager = [[GameManager alloc] init]; 
    }); 

    return sharedGameManager; 
} 

dispatch_onceは一度だけ実行されることが保証されるので、あなたのゲームマネージャは、上で初期化されません。あなたがそれを解放しない限り、それは生き続けるでしょう、そして、それはあなたのプログラムの最後に(そのstatic文脈のために)正しく解放されます。

+0

あなたは明らかにNSAssertの仕組みを理解していません... –

+0

@ RichardJ.RossIIIオイ、そうです。私はあまりにも素早く読んでいて、頭の中で物事を混同していました。あなたはまったく正しい。うわー。 –

+1

@ RichardJ.RossIIIとにかく、そのビットを削除するために私の答えを更新しました。 –

関連する問題