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();
d->Autorelease(); {
autorelease_newpool
Data *d = new Data();
d->Autorelease();
{
autorelease_newpool
Data *d = new Data();
d->Autorelease();
}
} Data *d1 = new Data();
d1->Autorelease(); return ;
}
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>); ++m_refcount; }
/*
* 引用计数减一
* 注意:
* - 只有对堆对象才能生效,栈对象不要使用
*/
void Release() { if (--m_refcount<=) delete this; }
/*
* 自动引用计数减一
* 注意:
* - 只有对堆对象才能生效,栈对象不要使用
*/
void Autorelease() { AutoreleasePoolMarager::GetInstance()->PeekTop()->AddRefObject(this); }
/*
* 获得引用计数
* 注意:
* - 只有对堆对象才能生效,栈对象不要使用
*/
int GetRefCount() { return m_refcount; }
protected:
RefObject():m_refcount() { }
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_;
原理和代码都比较简单,只要把几个类得关系理清楚就明白了。
C++模拟OC的多重自动释放池的更多相关文章
- OC对象,自动释放池,OC与C语言的区别
在C语言中,编程都是面向过程的编程,每一个代码块都严格按照从上至下的顺序执行,在代码块之间同样也是这样, 但是在OC中往往不是这样,OC和C++.java等语言一样,都是面向对象的编程语言,在代码的执 ...
- OC 内存泄露 自动释放池
花絮:看到下面的代码就想起这么一个调侃: 一个老程序员,功成名就,金盆洗手不在写代码后,决定练练书法.提笔思索良久后在纸上写下:Hello world! /********************** ...
- OC中对象元素的引用计数 自动释放池的相关概念
OC中数组对象在是如何处理对象元素的引用计数问题的,同时介绍一下自动释放池的相关概念 一.数组对象是如何处理对象元素的引用计数问题[objc] view plaincopy 1. // 2. / ...
- 63 (OC)* NSAutoreleasePool 自动释放池
目录 0:ARC 1: 自动释放池 2:NSAutoreleasePool实现原理 3:autorelease 方法 4: Runloop和Autorelease的关系 5: Using Autore ...
- OC学习篇之---数组对象的引用计数问题和自动释放池的概念
之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用: http://blog.csdn.net/jiangwei0910410003/article/de ...
- OC之property和自动释放池
property实例 property参数 自动释放池 一.property实例 1.前边的例子我们看到,我们在一个类中如果用到另外一个类的实例作为自己的成员变量时,通常需要在setter方法中,先r ...
- OC自动释放池autoreleasepool介绍
自动释放池的机制是:它使得应用在创建新对象时,系统能够有效地管理应用所使用的内存. @autoreleasepool { statements } 在创建新对象时,并且系统未启动ARC特性,那么在使用 ...
- Autorelease自动释放池的使用
Autorelease自动释放池的使用 使用ARC开发,只是在编译时,编译器会根据代码结构自动添加了retain.release和autorelease. MRC内存管理原则:谁申请,谁释放 遇到al ...
- 04-OC属性的使用、自动释放池、封装和继承
目录: 一.IOS6声明式属性的使用 二.autoreleasepool自动释放池 三.封装.继承 回到顶部 一.IOS6声明式属性的使用 注:声明式属性默认情况下,并没有解决内存问题, 当使用@pr ...
随机推荐
- Git查看与修改用户名、邮箱(转载)
用户名和邮箱的作用: 用户名和邮箱地址相当于你的身份标识,是本地Git客户端的一个变量,不会随着Git库而改变. 每次commit都会用用户名和邮箱纪录. github的contributions跟你 ...
- Hadoop初探
本文转自:https://blog.csdn.net/column/details/14334.html 前言 Hadoop是什么? 用百科上的话说:“Hadoop是一个由Apache基金会所开发的分 ...
- [转帖]通俗解释 AWS 云服务每个组件的作用
你有听说过 ContainerCache,ElastiCast 和 QR72 这些 AWS 的新服务吗? 没有就对了,这些都是我编的:) 不过,AWS 有 50 多个服务,从名称也不能看出这些服务是做 ...
- [转帖] Oracle 关闭自动收集统计信息
--关闭自动统计信息 https://blog.csdn.net/royzhang7/article/details/51172556 明天再仔细看一下. select client_name,sta ...
- macOS how to install python3
macOS how to install python3 macOS & Python 3.7.2 https://www.python.org/downloads/mac-osx/ http ...
- 【51Nod1847】奇怪的数学题
记\(f(x)=\)\(x\)的次大因数,那么\(sgcd(i,j)=f(gcd(i,j))\). 下面来推式子: \[ \begin{aligned} \sum_{i=1}^n\sum_{j=1 ...
- 洛谷 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 解题报告
P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 题意: 给定一个长\(N\)的序列,求满足任意两个相邻元素之间的绝对值之差不超过\(K\)的这个序列的排列有多少个? 范围: ...
- com.android.support:appcompat-v7 版本号问题
supportLibVersion 的头数字是和targetSdkVersion 版本一样的. ext { supportLibVersion = '22.2.1'} compile "co ...
- React事件传递参数
<button onClick={(ev) => {this.handleClick(ev,arg1,arg2,...)}} 用箭头函数,注意第一个参数一定要是事件参数.
- bzoj 1406
%%% PoPoQQQ x^2=kn+1 x^2-1=kn (x+1)(x-1)=kn 令x+1=k1*n1,x-1=k2*n2,其中k1k2=k,n1n2=n 因此我们可以枚举n的约数中所有大于等于 ...