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

CCNode 및 CCArray 의 메모리 관리

|
CCArray의 소멸자에서 CCArray에 들어있는 모든 CCObject형을 전부 삭제해주고 메모리 해제를 해준다.

CCArray::~CCArray()
{
    ccArrayFree(data);
}

/** Frees array after removing all remaining objects. Silently ignores NULL arr. */
void ccArrayFree(ccArray*& arr)
{
    if( arr == NULL ) 
    {
        return;
    }
ccArrayRemoveAllObjects(arr); //ccArray에 있는 모든 객체를 다 삭제
free(arr->arr);
free(arr);
arr = NULL;
}


CCNode 의 모든 객체들 addChilde및 removeChild를 할때 추가되는 객체들은 
CCNode 안의 CCArray 멤버변수 m_pChildren 에 저장이 되고 삭제가 되는등 관리가 된다.

CC_PROPERTY_READONLY(CCArray*, m_pChildren, Children)



CCNode::~CCNode(void)
{
    CCLOGINFO( "cocos2d: deallocing" );
    
    unregisterScriptHandler();

    CC_SAFE_RELEASE(m_pActionManager);
    CC_SAFE_RELEASE(m_pScheduler);
    // attributes
    CC_SAFE_RELEASE(m_pCamera);

    CC_SAFE_RELEASE(m_pGrid);
    CC_SAFE_RELEASE(m_pShaderProgram);
    CC_SAFE_RELEASE(m_pUserObject);

    if(m_pChildren && m_pChildren->count() > 0)
    {
        CCObject* child;
        CCARRAY_FOREACH(m_pChildren, child)
        {
            CCNode* pChild = (CCNode*) child;
            if (pChild)
            {
                pChild->m_pParent = NULL;
            }
        }
    }

    // children 등을 전부 삭제한다->CCArray가 삭제되고 CCArray의 소멸자가 생성되므로 위에 있는 것들이 실행되고
   //모든 객체들이 다 삭제된다.
    CC_SAFE_RELEASE(m_pChildren);
}


Trackback 0 And Comment 0

[IT 서적]시작하세요 cocos2d 아이폰 게임 프로그래밍! - 초보자를 위한 책

|



시작하세요 cocos2d 아이폰 게임 프로그래밍

저자
이재환 지음
출판사
위키북스 | 2011-10-12 출간
카테고리
컴퓨터/IT
책소개
[출판사서평]cocos2d for iPhone을 활용한 게임 개...
가격비교



많은 게임 회사들이 Unity-3d나 cocos2d를 이용해서 게임을 개발합니다. 그중에 2d쪽 게임을 개발할때는 좋은 퍼포먼스와 많은 라이브러리를 제공하는 cocos2d를 많이 씁니다. (Unity-3D로도 2d 게임을 개발 할 수 있지만, cocos2d 보다는 퍼포먼스 면에서 떨어진다고 합니다. 물론 3d쪽으로는 좋은 엔진입니다.)

 

  저는 mac 이 없는 관계로 windows 개발 환경에서도 안드로이드 게임을 개발 할 수 있는 좋은 방법이 없을까 고민 하던 중 cocos2d-x를 알아 보게 되었고, windows 환경에서도 cocos2d-x라는 멀티플랫폼을 지원하는 게임엔진에 대해서 알게 되었고, 그 매력에 빠져 들게 되었습니다.

cocos2d-x 는 이름에서 알 수 있듯이 cocos2d를 벤치마킹 해서 만든 엔진이며, cocos2d와는 달리 c++을 사용하며, 멀티플랫폼 게임엔진입니다.

지원하는 운영체제는 ios, android, bada, blackberry qnk , win32, linux , win8 metro, mac os X 등 많은 플랫폼을 지원합니다.

하지만 아직까지는 국내에 나와있는 cocos2d-x 전용 서적은 없으므로 cocos2d 서적을 보면서 공부를 해야되는 상황이었습니다.

 

  가장 먼저 이 책은 책이름에서 알 수 있듯이 초보자를 위한 서적입니다. 가장 기본적인 cocos2d의 기본 구조 및, 스프라이트(이미지)를 그리는 방법, 레이블 다루기, 메뉴 다루기, cocos2d의 강점인 action 사용하기, 타일맵 사용하기 등 cocos2d의 가장 기본적인 기능에 초점을 두고 만든 책 인거 같습니다. 만약 cocos2d에 대해 어느정도 알고 있고, 사용 할 수 있는 프로그래머라면 큰 도움은 되지 않을 것 같지만, 정말 초보자를 위해서 잘 작성된 책인 것 같습니다. 책 뒤에는 기본적인 게임을 만들 수 있는 예제도 수록 되있어, 초보자도 쉽게 익힐 수 있을 겁니다.(cocos2d의 듀토리얼과 거의 같은 수준의 예제 입니다.).

 

  일단 너무 기본적인 내용에 충실하기 때문에, 제가 이책을 보면서 실제로 게임을 개발 하려고 할때 , 파일들을 어떤식으로 관리하며 cocos2d-x의 경우 클래스를 어떤식으로 나누고 그 클래스에 어떤 변수나 함수를 설정해야 되나 막막했던 기억이 있습니다. 확실히 실무에 바로 써먹기에는 어려운 점이 있는 것 같습니다.

하지만 처음으로 공부를 하는 입장에서는 부담없이 보고 따라하면서 배울 수 있는 책인 것 같습니다. 

Trackback 0 And Comment 0