본문 바로가기

Development/IOS & Mac

Cocos2d-X iOS에서 완전히 종료시키기

본인의 경우 Cocos2d-x 와 iOS native를 ViewController 단위로 실행하게 만들면서 알게된 문제입니다.

Cocos2d x 의 버전은 cocos2d-2.0-x-2.0.4 입니다.


원래라면 


CCDirector::sharedDirector()->end();


호출을 하면 Cocos2d-x와 관련 된 모든 것들이 종료가 되어집니다. 하지만 프레임은 떨어지지 않지만 다시 실행시키면 시킬 수록 터치의 반응속도가 점점 떨어지는 것을 발견


원인은 CCDirectorCaller 클래스에서 문제가 있었습니다.


+(id) sharedDirectorCaller

{

    if (s_sharedDirectorCaller == nil)

    {

        s_sharedDirectorCaller = [CCDirectorCaller new];

    }

    

    return s_sharedDirectorCaller;

}


+(void) destroy

{

2. s_sharedDirectorCaller 의 Retain Count는 2이므로 dealloc이 호출되지 못함 그래서 doCaller 함수가 계속 호출 그리고 sharedDirectorCaller 호출시 다시 생성.....

    [s_sharedDirectorCaller release];

 s_sharedDirectorCaller = nil;

}


-(void) alloc

{

        interval = 1;

}


-(void) dealloc

{

    [displayLink release];

    [super dealloc];

}


-(void) startMainLoop

{

        // CCDirector::setAnimationInterval() is called, we should invalidate it first

        [displayLink invalidate];

        displayLink = nil;

        

        displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];

  1.위의 코드에서 self로 들어가면서 RetainCount가 증가 

 (다행히 displayLink를 멈추기에 Retina Count가 2이상 오르지 않음)

        [displayLink setFrameInterval: self.interval];

        [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

}


-(void) setAnimationInterval:(double)intervalNew

{

        // CCDirector::setAnimationInterval() is called, we should invalidate it first

        [displayLink invalidate];

        displayLink = nil;

        

        self.interval = 60.0 * intervalNew;

        

        displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];

 1.마찬가지........

        [displayLink setFrameInterval: self.interval];

        [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

}

                      

-(void) doCaller: (id) sender

{

    cocos2d::CCDirector::sharedDirector()->mainLoop();

}


그래서 본인이 나름대로?.... 다시 제대로 종료가 되어질수 있도록 개선을 하였습니다.


+(id) sharedDirectorCaller {

if (s_sharedDirectorCaller == nil) {

s_sharedDirectorCaller = [[CCDirectorCaller alloc] init];

}//end if

return s_sharedDirectorCaller;

}


+ (void) destroy {

        [s_sharedDirectorCaller stopMainLoop];

[s_sharedDirectorCaller release];

s_sharedDirectorCaller = nil;

}


- (id) init {

if ((self = [super init])) {

interval = 1;

}//end if

return self;

}//end init Method


- (void) dealloc {

    

    [super dealloc];

}


- (void) startMainLoop {

[self stopMainLoop];

displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];

[displayLink setFrameInterval: self.interval];

[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

}


- (void) stopMainLoop {

if (displayLink != nil) {

[displayLink invalidate];

displayLink = nil;

}

}


- (void) setAnimationInterval:(double)intervalNew {

[self stopMainLoop];

    

self.interval = 60.0 * intervalNew;

displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];

[displayLink setFrameInterval: self.interval];

[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

}


- (void) doCaller: (id) sender {

cocos2d::CCDirector::sharedDirector()->mainLoop();

}