autoRelease 및 retain() , release(), retainCount()

|

Cocos2d-x의 메모리 관리

Reference Count

레퍼런스카운터는 c와 c++의 메모리관리의 오래된 방법이다. ios에서는 8년전부터 이 메커니즘을 써왔다.
cocos2d-x에서도 ios ndk 의 NSAutoreleasePool와 거의 같은 CCAutoreleasePool이 존재한다 . 사용방법은 거의 동일하며 만약 너가 ios로 개발한 경험이 없으면 NSAutoreleasePool class Reference를 읽어봐라 


CCAutoreleasePool

CCAutoreleasePool 은 NSAutoreleasePool거의 같지만 2개의 차이점이있?다.

  1. CCAutoreleasePool 은NESTED에서 사용할수없다. 오직 게임 인스턴스에서만 사용 가능하다.
  2. CCAutoreleasePool 은 멀티쓰레드에서 사용할수 없다. 

CCAutoreleasePool의 로직은 간단하다 만약 너가l object->autorelease()을 실행하면 object는  autorelease pool 에 들어가게 된다. 

autorelease pool은 루프가 끝날시 자동으로 release()이 되게 도와준다. 

예를들어 layer->addChild(sprite), 이 sprite 는 레이어의 차일드이다, 이것은 레이어가 release될때까지 pool에서 유지된다


CCObject::release(), retain() and autorelease()

->release() 가 필요할때
1. "new" 연산자를 사용할때  CCSprite,CCLayer 등(CCObject를 상속받는 자식들)
2. "retain()"을 호출할때


release나 retain이 필요없는 예제:

CCSprite* sprite = CCSprite::spriteWithFile("player.png");


위 예제는 autorelease()풀에 의해서 관리되기때문에  release나 retain이 필요없다.


An Error Sample

bool HelloWorld::init()
{
    bool bRet = false;
    do
    {
        //////////////////////////////////////////////////////////////////////////
        // super init first
        //////////////////////////////////////////////////////////////////////////

        CC_BREAK_IF(! CCLayer::init());

        //////////////////////////////////////////////////////////////////////////
        // add your codes below...
        //////////////////////////////////////////////////////////////////////////

                CCSprite* bomb1 = CCSprite::spriteWithFile("CloseNormal.png");
                CCSprite* bomb2 = CCSprite::spriteWithFile("CloseNormal.png");
                CCSprite* bomb3 = CCSprite::spriteWithFile("CloseNormal.png");
                CCSprite* bomb4 = CCSprite::spriteWithFile("CloseNormal.png");
                CCSprite* bomb5 = CCSprite::spriteWithFile("CloseNormal.png");
                CCSprite* bomb6 = CCSprite::spriteWithFile("CloseNormal.png");

                addChild(bomb1,1);
                addChild(bomb2,1);
                addChild(bomb3,1);
                addChild(bomb4,1);
                addChild(bomb5,1);
                addChild(bomb6,1);

                m_pBombsDisplayed = CCMutableArray<CCSprite*>::arrayWithObjects(bomb1,bomb2,bomb3,bomb4,bomb5,bomb6,NULL);
                //m_pBombsDisplayed is defined in the header as a protected var.
                // <--- We should add m_pBombsDisplayed->retain() here to avoid crashing in HelloWorld::refreshData()

                this-]]>scheduleUpdate();
        bRet = true;
    } while (0);

    return bRet;
}

void HelloWorld::update(ccTime dt)
{
        refreshData();
}

void HelloWorld::refreshData()
{
        CCMutableArray<CCSprite*]]>::CCMutableArrayIterator iter = m_pBombsDisplayed-]]>begin();
        (*iter)-]]>setPosition(ccp(100,100));
}

이 예제의 실수는 m_pBombsDisplayed 는 CCMutalbeArray<CCSprite*>::arrayWithObjects 에 의해 생성되는데, autoRelease()에의해 관리되기때문에

루프가 지나면 사라진다. 
이문제를 해결하기 위해서는  m_pBombsDisplayed = CCMutableArray<CCSprite*]]>::arrayWithObjects(...); 뒤에 m_pBombsDisplayed->retain()를 추가하고, HelloWorld::~HelloWorld() 소멸자에서 m_pBombsDisplayed->release()한다.

Trackback 0 And Comment 0
prev | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ··· | 38 | next