2012-06-05 22 views
0

我用cocos2d version2.0打造一款遊戲,不使用ARC,發現問題:單身無效。cocos2d version2.0單身無效

我用兩個單例MACRO,問題一樣。

#ifndef SINGLETON_INTERFACE 
#define SINGLETON_INTERFACE(CLASSNAME)     \ 
    +(CLASSNAME*) sharedManager; 
#endif 

#ifndef SINGLETON_IMPLEMENTATION 
#define SINGLETON_IMPLEMENTATION(CLASSNAME)    \ 
                 \ 
+(CLASSNAME*) sharedManager {       \ 
    static dispatch_once_t pred;      \ 
    static CLASSNAME* shared##CLASSNAME = nil;   \ 
    dispatch_once(&pred, ^{       \ 
    shared##CLASSNAME = [[self alloc] init]; });  \ 
    return shared##CLASSNAME;       \ 
}               
#endif 

#ifndef SINGLETON_INTERFACE 
#define SINGLETON_INTERFACE(CLASSNAME)    \ 
    +(CLASSNAME*) sharedManager; 
#endif 

#ifndef SINGLETON_IMPLEMENTATION    
#define SINGLETON_IMPLEMENTATION(CLASSNAME)   \ 
\ 
static CLASSNAME* shared##CLASSNAME = nil;   \ 
\ 
+(CLASSNAME*) sharedManager       \ 
{             \ 
    if (shared##CLASSNAME != nil) {     \ 
     return shared##CLASSNAME;     \ 
    }            \ 
\ 
    @synchronized(self) {       \ 
     if (shared##CLASSNAME == nil) {    \ 
      shared##CLASSNAME = [[self alloc] init];\ 
     }           \ 
    }            \ 
\ 
    return shared##CLASSNAME;      \ 
}             \ 
\ 
+(id) allocWithZone:(NSZone*)zone     \ 
{             \ 
    @synchronized(self) {       \ 
     if (shared##CLASSNAME == nil) {    \ 
      shared##CLASSNAME = [super allocWithZone:zone]; \ 
      return shared##CLASSNAME;    \ 
     }           \ 
    }            \ 
    NSAssert(NO, @ "[" #CLASSNAME " alloc] explicitly called on singleton class."); \ 
    return nil;          \ 
}             \ 
\ 
-(id) copyWithZone:(NSZone*)zone     \ 
{             \ 
    return self;         \ 
}             \ 
\ 
-(id) retain          \ 
{             \ 
    return self;         \ 
}             \ 
\ 
-(unsigned) retainCount        \ 
{             \ 
    return UINT_MAX;        \ 
}             \ 
\ 
-(oneway void) release        \ 
{             \ 
}             \ 
\ 
-(id) autorelease         \ 
{             \ 
    return self;         \ 
} 
#endif 

使用:

[[CCDirector sharedDirector] replaceScene:[MenuScene sharedManager]]; 

的MenuScene再次顯示,但任何按鈕(CCMenu)或其他元件(CCNode)沒有響應。 我的意思是第一個電話,場景一切正常,再次打電話時,場景顯示,但菜單或其他元素沒有反應。 但是在cocos2d v1.0中運行得很好。

////////////////////////////////////////////// ////////////////////

我重寫了 「清理」 無 「[超級清理]」,類似這樣的:

-(void) dealloc 
{ 
    [super cleanup]; 
    [super dealloc]; 
} 

-(void) cleanup 
{ 
    // 
} 

現在,現場運行單身確定,但它安全嗎?

回答

2

的問題可能在於你的場景的孩子CCDirector進行「清理」行動。

的cocos2d V2.0增加了在一些情況下,其中獲得不管發生這種情況你單身是否留在內存「清理」過程中釋放的區塊。

從V2.0遷移指南:

設置清理標誌爲YES可能會導致應用程序的邏輯副作用它仍然以釋放資源,從而使隱含引用。 CCMenuItems在內部使用塊來啓動動作,可能會給出問題並且不會啓動動作,假設您已經從激活清除標誌並將其添加回來的父節點中刪除該項目,這是一個明顯跡象。簡單地將旗子改爲NO應該就足夠了。

遷移指南:http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:migrate_to_v2.0#ccsprite


隨口說說,我建議您:

  • 找到一種方法來安全地防止 「清理」 被稱爲你的單身的孩子。
  • 或者:將所有內容都保存爲顯示/隱藏的CCLayer的子項,而不是使用場景機制。
  • 或者:不要每次都使用一個singleton並重新創建場景。