Refactor #3519

By walzer@cocos2d-x.org Posted 2014-05-04 07:20

My Email:

=========



Indeed, I agree to move \`autorelease\` stuff outside of Object.

Now, in our Object class, there are some other variables and methods not refer to reference counting.



class CC_DLL Object

{

public:

unsigned int _ID; > Used only for Lua bindings

int _luaID; > Used only for Lua bindings

protected:

/// count of references

unsigned int _reference; —> (1) Used for reference counting

/// count of autorelease

unsigned int _autoReleaseCount; > Used for autorelease pool

public:

Object();

virtual ~Object();



inline void release() —> (1)

inline void retain() —> (1)



Object* autorelease(); > used for autorelease pool



bool isSingleReference() const; —> (1)

unsigned int retainCount() const; —> (1)



virtual bool isEqual(const Object* object); > should not be in Object

virtual void acceptVisitor(DataVisitor &visitor); > should not be in Object

virtual void update(float dt) {CC_UNUSED_PARAM(dt);}; > should not be in Object

};



We should only keep (1) , move all others out of our Object.



Problem:

--------



There will not autorelease() method for all objects. So the old code will not be able to work.



Sprite* Sprite::create(const std::string& filename)

{

Sprite *sprite = new Sprite();

if (sprite && sprite->initWithFile(filename))

{

sprite->autorelease(); // Broken here.

return sprite;

}

CC_SAFE_DELETE(sprite);

return nullptr;

}



My Idea:

--------



Since autorelease is just a method that adding an object to autorelease pool.



Object* Object::autorelease()

{

PoolManager::sharedPoolManager()->addObject(this);

return this;

}



So probably, we could define a macro like:



#define CC_AUTORELEASE_OBJECT(object) \

PoolManager::sharedPoolManager()->addObject(object);



Therefore, the Sprite::create will be :



Sprite* Sprite::create(const std::string& filename)

{

Sprite *sprite = new Sprite();

if (sprite && sprite->initWithFile(filename))

{

CC_AUTORELEASE_OBJECT(sprite);

return sprite;

}

CC_SAFE_DELETE(sprite);

return nullptr;

}



Yep, in fact, we don’t encourage developer to use \`autorelease\` stuff in their game codes. It’s hard to detect where to cause crash since autorelease delay the release operation.



We encourage them to write codes like:



MySprite* sp = new MySprite();

sp->init();



xxx



sp->release();

Back