看了引用计数之后 那时好像懂了 今天突然想起一个问题:
Scene也是继承自Ref 。然后也是静态生成一个autorelease后的对象 那计数就变成1了
class CC_DLL Scene : public Node
{
public:
/** creates a new Scene object */
static Scene *create();
{
Scene *Scene::create()
{
Scene *ret = new Scene();
if (ret && ret->init())
{
ret->autorelease();
return ret;
}
else
{
CC_SAFE_DELETE(ret);
return nullptr ;
}
}
}
}
main函数里面: 【每种颜色代表一个函数 颜色嵌套代表函数的调用 类似栈】
int APIENTRY _tWinMain (HINSTANCE hInstance ,
HINSTANCE hPrevInstance ,
LPTSTR lpCmdLine ,
int nCmdShow)
{
return Application::getInstance()->run();
当中run(){
while(!glview->windowShouldClose())
{
QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart
> _animationInterval.QuadPart)
{
nLast.QuadPart = nNow.QuadPart;
director->mainLoop();
当中mainLoop();
{
drawScene();
PoolManager::getInstance()->getCurrentPool()->clear();
for (const auto &obj
: _managedObjectArray)
{obj->release();}
}
glview->pollEvents();
}
else
{
Sleep(0);
}
}
}
}
我们看到蓝色代码那里,PoolManager::getInstance()->getCurrentPool()->clear();
这句代码会调用obj->release();把每一个增加autoreleasepool的对象进行release操作,好了问题就来了(不是挖掘面积)
Scene增加autorelease了 node继承的都增加了 Sprite也增加了 我们知道ref的构造函数是把引用计数自己主动变成1。那这里每一帧的绘画会把对象池里面的scene node sprite调用一次release 假设没有其它retain也就是变成0要回收了。可是不是这种,实际还是能够显示出来的
有两个地方 一个是scene的runWithScene一个是继承node的sprite这些等等
1、scene的runWithScene
【每种颜色代表一个函数 颜色嵌套代表函数的调用 类似栈】
bool AppDelegate ::applicationDidFinishLaunching() {
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLView::create("WeChat
Airplane" );
glview->setFrameSize(600,800);
director->setOpenGLView(glview);
}
director->setDisplayStats( true);
director->setAnimationInterval(1.0 / 60);
glview->setDesignResolutionSize(480, 800, ResolutionPolicy::SHOW_ALL );
this->setResourceSearchResolution();
auto scene = WelcomeScene::create();
director->runWithScene(scene);
runWithScene(scene){
pushScene( scene);
{
_scenesStack.pushBack( scene);
{
_data.push_back( object );
object ->retain();
}
}
}
return true;
}
从上面的代码 我们能够看到不妨retain了 所以scene是在mainloop里面的autoreleasepool减1 clear一次 可是他在_scenesStack retain了
那么就不会被回收了 那全部的node事实上都是加入到scene里面的。也就不会由于release Scene而导致node减1
2、继承node的sprite这些等等
我们知道都要addChild的 layer也好 node也好 sprite也好 都是要加进去的
void Node::addChild(Node *child)
{
CCASSERT( child != nullptr , "Argument
must be non-nil" );
this->addChild(child, child->_localZOrder, child->_tag);
{
void Node ::insertChild( Node* child, int z)
{_transformUpdated = true ;_reorderChildDirty =true;_children.pushBack(child);
void pushBack(T object ){CCASSERT (object != nullptr , "The object should not be nullptr" );_data.push_back( object );object ->retain();}child->_setLocalZOrder( z);}
}
}
从上面的调用来看 我们能够看到最后的调用还是用了object ->retain();
所以mainloop里面autoreleasepool 调用release是把2变成1 然后autoreleasepool 已经把vector存的内容clear下一帧就不会调用了