不得不说,人太容易忘记,一段时间不用的东西就会忘,导致范下一些不该犯下的错误。
cocos2dx的内存管理:
创建node,引用计数为1,并加入到autorelease(自动释放池中),如果addChild把该node加入到其他node时,引用计数+1,变为2。主循环下一帧的时候,会把 自动释放池中得对象,引用计数减1,如果为0,就自动释放,不为0,从自动释放池中删除。
这样就导致一个问题,如果你现在创建的对象没有节点可以加,下一帧或下下帧的时候会用到,怎么办?(例:游戏或系统的提示消息,可能会用同时好多条的情况,你不能一下全显示出来,体验和细节不好。你只能把消息存到一个 队列中,在主循环中 一帧处理一条消息(显示出来,并从队列中弹出),如果队列中存的是 创建好的cocos2dx node, 就会导致这种情况,一帧创建了好几个node,但是没及时处理)
node->retain();主动使引用计数+1,这样在一帧的时候就不会被自动释放池 释放
node->release(); 主动使引用计数-1,为0,释放。(一一对应关系,你用了几次retain,就要用几次release,否则内存泄露,removeChild,removeFromParent... 内部调用的也是release()函数)
介绍几个cocos2dx 宏:
我对宏本身就有种胆怯的情怀,而引擎中又太多。
#define CC_SAFE_RELEASE_NULL(p) do { if(p) { (p)->release(); (p) =0; } } while(0) //release一个对象,并把指针置为0(NULL) relase函数中如果对象本身的引用计数为0,断言 CCAssert(false)会断。
CCAssert(m_uReference > 0,"reference count should greater than 0");
#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
__TYPE__ *pRet = new __TYPE__(); \
if (pRet && pRet->init()) \
{ \
pRet->autorelease(); \
return pRet; \
} \
else \
{ \
delete pRet; \
pRet = NULL; \
return NULL; \
} \
}
作用:为特定的node子类,添加一个create 函数, 该类的初始化会主动调用该类的 init() 函数,并把该node加入到自动释放池中,如果写组件,这个宏非常有用。