Cocos2d-x 的内存管理(9)
看下面的代码:
vector<CCSprite*> sprites;
for (int i = 0; i < 3; ++i) {
CCSprite *helloworld = new CCSprite;
if (helloworld->initWithFile("HelloWorld.png")) {
CCSize size = CCDirector::sharedDirector()->getWinSize();
// position the sprite on the center of the screen
helloworld->setPosition( ccp(size.width/2, size.height/2) );
// add the sprite as a child to this layer
scene->addChild(helloworld, 0);
sprites.push_back(helloworld);
helloworld->release();
scene->removeChild(helloworld);
}
}
因为C++的容器是对Cocos2d-x的引用计数没有影响的, 所以在上述代码运行后, 虽然vector中保存者sprite的指针, 但是其实都已经是野指针了, 所有的sprite实际已经析构调了. 这种情况相当危险. 把上述代码中的vector改成cocos2d-x中的CCArray就可以解决上面的问题, 因为CCArray是对引用计数有影响的.
见下面的代码:
CCArray *sprites = CCArray::create();
for (int i = 0; i < 3; ++i) {
CCSprite *helloworld = new CCSprite;
if (helloworld->initWithFile("HelloWorld.png")) {
CCSize size = CCDirector::sharedDirector()->getWinSize();
// position the sprite on the center of the screen
helloworld->setPosition( ccp(size.width/2, size.height/2) );
// add the sprite as a child to this layer
scene->addChild(helloworld, 0);
sprites->addObject(helloworld);
helloworld->release();
scene->removeChild(helloworld);
}
}
改动非常小, 仅仅是容器类型从C++原生容器换成了Cocos2d-x从Objc模拟过来的array, 但是这段代码执行后, sprites中的sprite都可以正常的使用, 并且没有问题. 可参考cocos2d-x的源代码ccArray.cpp:
/** Appends an object. Behavior undefined if array doesn't have enough capacity. */
void ccArrayAppendObject(ccArray *arr, CCObject* object)
{
CCAssert(object != NULL, "Invalid parameter!");
object->retain();
arr->arr[arr->num] = object;
arr->num++;
}
但是, 假如我就是想用C++原生容器, 不想用CCArray怎么办呢? 需要承担的风险就来了, 有的时候还行, 比如上例, 我只需要去掉helloworld->release那一行, 并且明白此时所有权已经是属于vector了, 在vector处理完毕后, 再release即可.
而有的时候这就没有那么简单了. 特别是Cocos2d-x因为依赖引用计数, 不仅仅是addChild等容器添加会增加引用计数, 回调的设计(模拟objc中的delegate)也会对引用计数有影响的. 曾经有人在初学Cocos2d-x的时候, 问我cocos2d-x有没有什么设计问题, 有没有啥坑, 我觉得这就是最大的一个.
举个简单的例子, 我真心不喜欢引用计数, 所以全用C++的容器, 写了下面这样的代码: (未编译测试, 纯示例使用)
class Enemy
{
相关新闻>>
- 发表评论
-
- 最新评论 更多>>