2012-04-19 42 views
2

我不明白使用NSAssert的+alloc,當+alloc+sharedGameManager叫,靜態_sharedGameManager變量是nil(所以NSAssert應停止執行首次[self alloc] init]叫...)Singleton中的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; 
} 

感謝您的回答

回答

3

您是否想到NS安置錯誤?如果_sharedGameManager

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

會拋出異常。它聲明表達式爲TRUE,它表示「我聲稱這肯定是這種情況」,因此_sharedGameManager必須爲零,否則會引發異常。這隻有在您嘗試創建此類的2個實例時纔會發生。

+0

哦,是的,我不明白爲什麼我確定它是相反的:)謝謝你的答案! – Paul 2012-04-19 23:25:07

0

這看起來像一對粘在一起的片段; alloc是一個實例方法,而不是一個類方法(靜態)。如果要執行單例類的初始化,請使用+(void)initialize

Objective-C運行時聲明保證此類方法只執行一次,因此它是設置單例的有效機制。要進一步閱讀,請點擊Mike Ash的主題blog post

+1

'+ alloc' _is_一個類的方法。否則,你是對的 - 看起來保羅似乎有兩個不相關的片段放在一起。每個人都需要使用'dispatch_once'來創建單例,而不是Apple給出的模式。 – 2012-04-19 22:15:19

+0

@wobbals:感謝wobbals,好的謝謝你的提示,我在一本書中發現了這個代碼,你對這個NSAssert有什麼看法?這是一個錯誤嗎?它可以像那樣工作嗎?如果是這樣,我不明白爲什麼 – Paul 2012-04-19 22:45:51

+0

嗯,它看起來不像兩個無關的片段。兩種方法只能在彼此在場的情況下工作。 – hooleyhoop 2012-04-19 23:16:37

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是如何工作的...... – 2012-04-19 22:24:48

+0

@ RichardJ.RossIII Oy,你說得對。我讀得太快了,混淆了我的腦海。你是完全正確的。哎呦。 – 2012-04-19 22:30:11

+1

@ RichardJ.RossIII無論如何,更新我的答案以消除這一點。 – 2012-04-19 22:34:15