게임 개발/Cocos2d-x

Cocos2d-x 3.0 beta에 새로 생긴 Vector, std::vector 대신 사용할 수 있을까?

날개 2014. 1. 13. 22:26


이번에 Cocos2d-x 3.0 베타버전을 받아 보거나, 사이트에서 변경사항을 살펴보면, 이번 버전부터 cocos2d::Vector와 cocos2d::Map을 지원한다는 점을 봤을겁니다.


간단히 말해서, 기존의 cocos2d::CCArray (2.x) 혹은 cocos2d::Array (3.0알파) 대신에 cocos2d::Vector를, cocos2d::CCDictionary (2.x) 혹은 cocos2d::Dictionary (3.0알파) 대신에 cocos2d::Map을 사용하라는 것이지요.


그런데, 새로 생긴 cocos2d::Vector나 cocos2d::Map을 살펴보면, 마치 C++ 표준인 std::vector나 std::map과 유사하게 생겼습니다.


그래서 그런지, cocos2d::Vector 대신에 그냥 std::vector를 써도 되는가? 라는 질문을 하시는 분들이 계시더군요.


결론적으로, 상황에 따라 다르지만 cocos2d::Array (혹은, cocos2d::CCArray) 대신에 사용할 목적이라면, 안된다고 말씀드리고 싶습니다.


물론 cocos2d-x의 객체(cocos2d::Object나 cocos2d::Node객체 등등)가 아닌 경우는 상관이 없겠지만, cocos2d-x의 클래스를 상속받은 cocos2d-x의 객체의 경우, 상황에 따라 문제가 생길 수 있을것 같습니다.



문제점 1 : 메모리 관리에서 문제가 발생 할 수 있습니다.


잘 알다시피, cocos2d-x는 아이폰용 cocos2d에서 나왔기 때문에, cocos2d-x 3.0에 이르러서는 완전히 Objective C문법에서 탈피했다고는 하나, Auto Release 개념은 그대로 사용을 하고 있습니다. (물론 Auto Release 방식이 Objective C의 고유 방식의 메모리 관리 기법은 아닙니다. 기법적인 부분으로 여러 언어에서 구현해서 사용하고 있습니다. 예를 들어, MS의 COM 라이브러리의 경우 C++를 사용하여 유사한 방식을 사용합니다.)


따라서 상황에 따라 retain()이나 release()함수가 불려져야 할때가 있습니다.


실제로 cocos2d-x의 Vector 클래스의 소스를 열어보면, 전달받은 객체의 retain()이나 release()가 불리는 부분이 여럿 있음을 발견할 수 있습니다.


예를 들어, push_back()의 경우,


    void pushBack(T object)

    {

        CCASSERT(object != nullptr, "The object should not be nullptr");

        _data.push_back( object );

        object->retain();

    }



보시는 바와 같이 전달받은 오브젝트의 retain()이 불립니다.


반약에 그냥 std::vector를 사용할 경우 저런 cocos2d-x 오브젝트의 처리를 해 주지 못하겠지요.



문제점 2 : 표준 vector에는 없는 cocos2d-x 오브젝트를 위한 메소드가 구현되어 있습니다.


예를 들어, cocos2d::Array(또는 CCArray)를 사용한 경우, 필요한 오브젝트를 배열에서 삭제하기 위한 방법중 Cocos2d-x 오브젝트를 넘겨서 삭제하는 방법이 있습니다. 


cocos2d::Vector는 이것을 그대로 지원합니다. 아래와 같이요....


// mySprites->removeObject(pBlockSprite);       // 2.x 또는 3.0알파 버전 방식

//

// 를, 아래와 같이 바꿈


mySprites.eraseObject (pBlockSprite);            // 3.0 베타 버전 방식



그러나 표준 std::vector에는 erase()는 있어도, eraseObject()는 없습니다. 게다가 release()함수를 호출해 주지도 않지요.



문제점 3 cocos2d-x 에서 제공하는 함수들이 파라미터로 cocos2d::Vector를 요구합니다.


상당수의 cocos2d-x 함수들이, 이제는 cocos2d::Vector를 파라미터로 받고 있습니다.


따라서 표준 std::vector를 사용할 경우 호환이 되지 않습니다.


몇가지만 예를 들자면,


Menu* Menu::createWithArray(const Vector<MenuItem*>& arrayOfItems)

Animation* Animation::createWithSpriteFrames(const Vector<SpriteFrame*>& frames, float delay/* = 0.0f*/)

...

...

...


이런식으로 말이죠.


(같은 이유로 더이상 cocos2d::Array(또는 CCArray)나 cocos2d::Dictionary(또는 CCDictionary)는 사용하지 않기를 추천합니다. Deprecated 되었다는 경고 메시지도 보기 싫지만, 아예 에러가 날 수 있는 이러한 상황들도 있습니다.)




여하튼, 결론은...


'엔진에서 제공하는 것은, 엔진에서 하라는 대로 사용하자' 입니다.


가장 에러를 줄이고 안전하게 사용하는 방법입니다.




PS. 이 글은 cocos2d-x 베타 버전을 사용한지 얼마 안되어 쓴 글이기 때문에 오류가 있을 수 있습니다.



끝.