一、场景对象体系
二、场景对象生命周期管理
场景对象的生命周期,不适合采用原始的c++管理方式, 即由使用者自己负责删除。而应该采用引用计数方式, 自动负责删除。
采用引用计数方式, 目前用法比较广的分两类:
1、智能指针, 如boost::shared_ptr, 这种方式原理是基于c++对象的生命周期和析构函数来实现的, 而且引用计数是由智能指针对象保存的。在这种方式下, 对象的传递和引用都是使用智能指针对象, 例如:
class A; typedef boost::shared_ptr<A> TAPtr; //B需要保留对A的引用 class B { public: void AccessA(TAPtr a) { m_a = a; //省略 }; private: TAPtr m_a; }; //C不需要保留对A的引用, 而仅仅是在某个接口中要访问A class C { public: void AccessA(TAPtr a) { //省略, 访问a }; };
这种方式的优点:
使用者没有任何负担。
缺点:
[1] 效率低。
[2] 不方便暴露对象给lua使用。
2、cocos2d中的Ref方式, 即由对象自身来保存当前的引用数, 并且由对象的使用者自己来负责增加引用数retain和减少引用数release。 在这种方式下, 对象的传递和引用都是使用对象指针来实现, 例如:
class A: public Ref; //B需要保留对A的引用 class B { public: ~B() { if(m_a) { m_a.release(); m_a = NULL; } } void AccessA(A *a) { m_a = a; m_a.retain(); //省略 }; private: A *m_a; }; //C不需要保留对A的引用, 而仅仅是在某个接口中要访问A class C { public: void AccessA(A *a) { //省略, 访问a }; };
这种方式的优点是:
[1] 效率高, 无论是传递、访问还是对于引用计数的操作(由使用者本身决定是否要调用retain和release)。
[2] 方便把对象暴露给Lua使用。
缺点是:
增 加了使用者自身的负担, 很容易造成内存泄露, 这正是因为由使用者本身决定是否要调用retain和release引起的。基于相同的原因, 如果要用容器(比如list, vector等)来保存对象时, 标准库中的容器没办法直接使用, 而必须封装, 或者在插入和删除元素是, 手动调用元素的retain和release.
时间: 2024-10-16 01:45:30