Cocos2d-x 的内存管理(8)
// part code of applicationDidFinishLaunching in AppDelegate.cpp
// create a scene. it's an autorelease object
CCScene *scene = HelloWorld::scene();
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);
helloworld->release();
}
这里暂时不管HelloWorld::scene, 先关注CCSprite的创建和使用, 这里使用new创建了CCSprite, 然后使用scene的addChild函数, 添加的到了scene中, 并显示. 一段这样简单的代码, 但是背后的东西却很多, 比如, 为啥我在scene的addChild后, 调用了sprite的release函数呢?
还是可以从引用计数的所有权上说起(这样比较好理解, 虽然你也可以死记哪些时候具体引用计数的次数是几). 当我们用new创建了一个Sprite时, 此时Sprite的引用计数为1, 并且所有权属于helloworld这个指针, 我们在把helloworld用scene的addChild函数添加到scene中后, helloworld的引用计数此时为2, 由helloworld指针和scene共享所有权, 此时, helloworld指针的作用其实已经完了, 我们接下来也不准备使用这个指针, 所有权留着就再也释放不了了, 所以我们用release方法特别释放掉helloworld指针此时的所有权, 这么调用以后, 最后helloworld这个Sprite所有权完全的属于scene.
但是我们这么做有什么好处呢? 好处就是当scene不想要显示helloworld时, 直接removeChild helloworld就可以了, 此时没有对象再拥有helloworld这个sprite, 引用技术为零, 这个sprite会如期的释放掉, 不会导致内存泄漏.
比如说下列代码:
// create a scene. it's an autorelease object
CCScene *scene = HelloWorld::scene();
// CCSprite* sprite = CCSprite::create("HelloWorld.png");
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);
helloworld->release();
scene->removeChild(helloworld);
}
上面的代码helloworld sprite能正常的析构和释放内存, 假如少了那句release的代码就不行.
容器对引用计数的影响
这个部分是引用计数方法都会碰到的问题, 也就是引用计数到底在什么时候增加, 什么时候减少.
在cocos2d-x中, 我倒是较少会像在objc中手动的retain对象了, 主要的对象主要由CCNode和CCArray等容器管理. 在cocos2d-x中, 以CC开头的, 模拟Objc接口的容器, 都是对引用计数有影响的, 而原生的C++容器, 对cocos2d-x的对象的引用计数都没有影响, 这导致了人们使用方式上的割裂. 大部分用惯了C++的人, 估计都还是偏向使用C++的原生容器, 毕竟C++的原生容器及其配套算法算是C++目前为数不多的亮点了, 比objc原生的容器都要好用, 更别说Cocos2d-x在C++中模拟的那些objc容器了. 但是, 一旦走上这条路就需要非常小心, 要非常明确此时每个对象的所有权是谁.
相关新闻>>
- 发表评论
-
- 最新评论 更多>>