2012-06-05 8 views
0

나는 ARC를 사용하지 않고 cocos2d version2.0 게임을 사용하여 문제를 찾습니다. 싱글 톤은 유효하지 않습니다.cocos2d version2.0 singleton invalid

두 개의 싱글 톤 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은 매우 뛰어납니다.

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

나는이 같은없이 "정리" "[슈퍼 정리]"오버라이드 (override) :

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

-(void) cleanup 
{ 
    // 
} 

, 싱글 톤을 실행하는 장면은 괜찮 았지만 안전하게 처리 할 수 ​​있습니까?

답변

2

문제는 아마도 Scene의 하위에서 "정리"작업을 수행하는 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의 하위 항목으로 모든 것을 메모리에 유지하십시오.
  • 또는 : 싱글 톤을 사용하지 않고 매번 장면을 다시 만듭니다.