Cocos2dx управление памятью, как использовать деструкторы и когда выпускать obejcts?

Я читаю по сети и документации, но, честно говоря, я не понимаю. Поскольку я новичок в cocos2d-x, я хотел бы лучше понять, как создаются/сохраняются объекты и что я должен делать для их выпуска (при необходимости). То, что меня смущает, - это использование умных указателей, которые я не очень хорошо знаю.

Представьте, что в моем CCLayer (добавленном в CCScene) я добавляю CCSprite, поэтому я делаю:

this->sprite = CCSprite::create("mySprite.png");
this->addChild(sprite);

то, так как я использовал create(), я должен выпустить его где-нибудь? в деструкторе CCLayer, может быть? или я не имею ничего общего с этим?

Я знаю основы С++, поэтому, если я делаю "новый" объект, на самом деле я должен удалить его в деструкторе или когда мне это больше не нужно, но как насчет объектов cocos2dx?

Ответ 1

Вот что,

Объект class Ref или любой полученный из него класс имеет переменную _retainCount, которая представляет область действия объекта.

Также существует пул autorelease, который похож на сборщик мусора в java. Объект, добавленный в этот пул autorelease, будет удален в конце фрейма. Если его _retainCount!=0

Теперь, когда вы создаете новый объект Ref или производного класса с помощью метода create, он уже добавлен в пул autorelease, и вам не нужно release его или delete его в любом месте. Как вы можете видеть в функции создания Node ниже.

Node * Node::create()
{
    Node * ret = new (std::nothrow) Node();
    if (ret && ret->init())
    {
        ret->autorelease();
    }
    else
    {
        CC_SAFE_DELETE(ret);
    }
    return ret;
}

Но когда вы создаете новый объект с помощью "нового", вам обязательно нужно delete после его использования. Хотя не рекомендуется использовать New для allocate объектов классов cocos2d. Скорее используйте create.

Node* temp=Node::create();

то

temp->retain();

//your work...

temp->release();

или

Node* temp=Node::create();
Node* tempChild=Node::create();
temp->addChild(tempChild);
//your work...
temp->removeFromParent();

Во-вторых,

когда ваш объект добавляется в пул autorelease, но вам нужно увеличить его область действия, вы можете просто сохранить его, это увеличивает его количество удержания на единицу, а затем вы должны вручную освободить его, то есть уменьшить его количество удержания после его использование завершено.

Третья вещь,

Всякий раз, когда вы добавляете дочерний объект, он сохраняется автоматически, но вам не нужно release его скорее вы удаляете из родителя, как указано выше.

Официальная документация - это @link ниже.

[http://www.cocos2d-x.org/wiki/Reference_Count_and_AutoReleasePool_in_Cocos2d-x#Refrelease-retain-and-autorelease][1]

Ответ 2

Извините, мой английский плохой!

1. this->sprite будет автоматическим выпуском, когда CCLayer уничтожит, если вы вызываете CCSprite::create(...); и addChild(...);.

2.если вы хотите удалить this->sprite иногда, вы могли бы назвать это:

this->sprite->removeFormParents();
this->sprite=NULL;

Ответ 3

Cocos2d-x использует objective-c -подобную систему управления памятью, так что переменные сохраняют счет. При каждом уходе за концом основного объекта кокоса "сохраняются счетные сокращения" и когда он достигает 1, он отпускается. CCObject, содержащий другие объекты, сохраняет их в живых, увеличивая их количество удержаний. Так что CCObjects сохраняет себя и обычно вам не нужно беспокоиться об управлении памятью. Однако есть ситуации, в которых вы хотели бы отключить автозапуск и вручную управлять временем жизни CCObjects с помощью функции сохранения() и release(). Существуют некоторые распространенные ситуации с cocos2d-x, приводящие к утечкам памяти, такие как наличие CCObject, связанного с другим CCObject, который сохраняет первый из них с помощью setUserObject(). Таким образом, оба никогда не будут уничтожены.

Таким образом, в общем, в большинстве случаев лучше всего придерживаться встроенной модели autorealse и вручную управлять некоторыми случаями краев, что обычно приводит к утечкам памяти. Кроме того, имейте в виду, что есть противоположные ситуации - т.е. доступ к мертвому ccobject может привести к ошибке выполнения.

Offtopic: вам не нужно писать это при доступе к члену/методу.