在Node中有几个以remove开头的方法:
removeChild、removeAllChildren、removeByName、removeByTag和removeFromParent。
这几个函数都有个控制变量bool cleanup,这个cleanup在使用的时候需要注意当前Node对象的_refCountNum问题。
比如: auto sprite = Sprite::Create("sprite.png"); 当前的refCount=1;
addChild( sprite )后,refCount = 2;
sprite->runAction( Action )后,refCount = 3;
当程序跑完一个frame后,在AutoRleasePoll中会使得当前的sprite的refCount-1;所以当前的sprite的refCount = 2;
如果在sprite作用域内调用了removeChild( sprite, true );此时sprite对象将被完全的释放掉,并且当前的sprite将成为野指针,我们在之后就不应该在使用这个sprite了,如果sprite是个成员变量的话,记得不要在去引用这个sprite。
如果在调用removeChild( sprite, false );此时sprite这个对象并没有被delete掉。虽然它会被当前的this中的_children erase掉。但是这个对象的内存没有释放,原因是以为在sprite调用runAction的时候sprite的refCount+1导致的。如果sprite是成员变量,我们在其他地方如果要想使用它需要再次调用addChild来完成显示。并且不用调用retain方法,当前的sprite被add后,它的refCount=2。
总结: remove方法只要cleanup=true,被remove的node就将被完全释放。但是cocos2d中并没有把这个node指针置为nullptr,我们不应该去引用这个被remove的node了,若cleanup=false,这个时候情况比较复杂。关键看有没有对象引用了它,意思就是有没有使得这个对象的refCount++,如果有,这个对象将不会被delete,如果没有即使cleanup=false,这个对象也会被delete掉。
cleanup主要是clean掉action和schedule,所以程序中尽量要保证cleanup=true去remove掉这个node。
场景切换时会将与这个action绑定的这个对象的refCount--;所以不会导致内存泄露的问题,setNextScene中解释了为什么会使这个对象的refCount--;
网友评论