The sprite pointer being NULL is not the problem, but rather that it’s pointing to invalid memory, because the sprite has already been released. It’s an auto-release object, so if nothing calls retain
on it to increase the reference count by 1 (see class Cocos2d::Ref
), then on the next update loop it will be deleted by the PoolManager
.
Assuming that is the issue, you would fix it like this:
std::vector<tlEntry> spriteEntries;
// Create sprite
tlEntry entry;
entry.s = Sprite::createXYZ() // Whatever creation method you want to use. Reference count = 1 here, and it is added to the auto-release pool (via a call to autorelease() in the create method)
entry.s->retain(); // retain the sprite, so increases ref count by 1, so now ref count = 2
spriteEntries.push_back(entry);
Now say you’ve reached the end of this, and we’re on the next update loop.
Director::mainLoop()
calls PoolManager::getInstance()->getCurrentPool()->clear();
to release all objects in the pool
The PoolManager checks the auto-release object collection, and for each item, it decrements the reference count by 1.
So, for this sprite, ref count = 2 - 1 = 1
The PoolManager then checks if ref count == 0, and if it is, it calls object->delete()
. In this case, the sprite still has a ref count of 1.
All objects in the auto-release pool collection are removed, so they will no longer automatically checked in future updates
At this point the sprite you created has a ref count = 1. The only way this sprite can be removed and memory associated with it properly freed is to call release()
on it, which is what you are responsible for.
So, when you no longer need the sprite in the list, you do this:
addChild(entries.front().s); // sprite added to a parent, which calls retain() on it, so now ref count = 2.
// At any point you want to remove the sprite/sprites from the list, you cannot simply call std::vector::clear()
. You need to call release
on all of the sprite first, then clear the list
for (auto&& entry : spriteEntries)
{
entry.s->release();
}
spriteEntries.clear();
If you just want to remove 1 sprite from the list, for instance, the entry at the end, then do this:
auto entry = spriteEntries.pop_back(); // Removes the entry from the list
entry.s->release(); // Release/free the sprite. You can also call CC_SAFE_RELEASE_NULL(entry.s) or CC_SAFE_RELEASE(entry.s) instead