C++模拟OC的多重自动释放池
使用过OC的都知道,OC的引用计数机制用起来还比较方便。于是就仿照OC的形式搞了个C++引用计数。
支持多重自动释放池,每次autorelease都会放到栈顶的自动释放池中。
自动释放池也可以像变量一样有生命周期,在退出block时自动销毁池,并且对池中每个对象调用release.
使用大概如下:
int main(int argc, char * argv[]) { USING_NAMESPACE_BASE using namespace std; Data *d = new Data(1); d->Autorelease(); { autorelease_newpool Data *d = new Data(3); d->Autorelease(); { autorelease_newpool Data *d = new Data(4); d->Autorelease(); } } Data *d1 = new Data(2); d1->Autorelease(); return 0; }
Github:【点击】
概述:
* - AutoreleasePool 自动释放池类
* - AutoreleasePoolLifecycleManager 池生命周期类,用于程序块内的池入栈和出栈控制
* - AutoreleasePoolMarager 池管理器,内部使用栈式结构管理池
* - RefObject 引用计数基类,提供引用计数的支持
关系梳理:
- 继承自RefObject的类具有,引用计数功能。当调用RefObject的autorelease时,其会通过AutoreleasePoolMarager获得栈顶的AutoreleasePool对象,然后将自己放入pool中。
- AutoreleasePoolMarager是单例,其内部使用栈式结构保存了一个或多个AutoreleasePool对象,供其他对象调用入栈新pool或者出栈销毁pool
- AutoreleasePool管理池中的对象,在pool销毁时会将所有池中RefObject对象release一遍
- AutoreleasePoolLifecycleManager作用就是在构造函数中入栈新pool,在析构函数中出栈pool
RefObject
class RefObject{ public: /* * 引用计数加一 * 注意: * - 只有对堆对象才能生效,栈对象不要使用 */ void Retain() { assert(m_refcount>0); ++m_refcount; } /* * 引用计数减一 * 注意: * - 只有对堆对象才能生效,栈对象不要使用 */ void Release() { if (--m_refcount<=0) delete this; } /* * 自动引用计数减一 * 注意: * - 只有对堆对象才能生效,栈对象不要使用 */ void Autorelease() { AutoreleasePoolMarager::GetInstance()->PeekTop()->AddRefObject(this); } /* * 获得引用计数 * 注意: * - 只有对堆对象才能生效,栈对象不要使用 */ int GetRefCount() { return m_refcount; } protected: RefObject():m_refcount(1) { } virtual ~RefObject() { } private: int m_refcount; };
AutoreleasePool
class AutoreleasePool { public: AutoreleasePool(); ~AutoreleasePool(); /* * 添加对象到自动释放池中 * 说明: * - 此对象必须为RefObject的子类 */ void AddRefObject(RefObject *refobject); /* * 对池中所有对象调用一次Release方法 * 说明: * - 此方法一般不要手动调用,在析构中会自动调用 * - 调用顺序为,先进的先调用(类似队列结构) */ void ReleaseAll(); private: std::vector<RefObject*> m_refobjects; };
AutoreleasePoolMarager
class AutoreleasePoolMarager { public: static AutoreleasePoolMarager* GetInstance(); static void DestroyInstance(); /* * 创建一个新的自动释放池,并且入栈 */ void PushNew(); /* * 将栈顶的自动释放池出栈,并删除 */ void PopTop(); /* * 获取栈顶的自动释放池,并不会删除 */ AutoreleasePool* PeekTop(); private: AutoreleasePoolMarager(); ~AutoreleasePoolMarager(); private: static AutoreleasePoolMarager* s_instance; std::stack<AutoreleasePool*> m_poolstack; };
AutoreleasePoolLifecycleManager
这个类的作用就是利用其对象的生命周期,来入栈和出栈自动释放池
class AutoreleasePoolLifecycleManager { public: /* * 构造函数中,入栈一个新的自动释放池(AutoreleasePool) */ AutoreleasePoolLifecycleManager() { AutoreleasePoolMarager::GetInstance()->PushNew(); } /* * 析构函数中,出栈自动释放池 */ ~AutoreleasePoolLifecycleManager() { AutoreleasePoolMarager::GetInstance()->PopTop(); } };
使用宏代替实例化AutoreleasePoolLifecycleManager对象
#define autorelease_newpool \ torch::AutoreleasePoolLifecycleManager __arplm_obj_;
原理和代码都比较简单,只要把几个类得关系理清楚就明白了。
Published with Luweimy