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 ...
随机推荐
- Sysprep错误一则
准备搭建一台基于Windows2008的域控,通过ISO文件装完系统后,照例使用Windows Update打全了补丁.同时,考虑到经常使用Powershell,所以手动再装上了PS5.1 .因为准备 ...
- Flexpod的开关机顺序
Flexpod = Cisco UCS + Cisco Nexus + Netapp (中文名叫做“融合基础架构”) 之前没有接触过这套系统,不太明白怎么个开关机的顺序,借公司停电的机会实际演练了一番 ...
- ByValue和ByPropertyName的区别
ByValue 以Get-Service命令为例,它的帮助文件中关于-Name参数是这样解释的: 1. "WinRM" | Get-Service 2. "Trusted ...
- find K maximum value from an unsorted array(implement min heap)
Maintain a min-heap with size = k, to collect the result. //Find K minimum values from an unsorted a ...
- Redis和Memcache的区别总结-京东阿里面试
集群: redis 和memcached都支持集群 数据类型 Redis支持的数据类型要丰富得多,Redis不仅仅支持简单的k/v类型的数据,同时还提供String,List,Set,Hash,Sor ...
- Cannot create file"C:\Users\LML\AppData\Local\Temp\EditorLineEnds.ttr"。另一个程序正在使用此文件,进程无法访问。
不能二次启动,每次开机第一次都ok,出于习惯,总是想试试第二次打开软件是否正常,结果不出所料,出现了“Cannot create file"C:\Users\LML\AppData\Loca ...
- 深入理解JAVA虚拟机阅读笔记1——JAVA内存区域
一.Java内存区域 1.程序计数器 线程私有. 当前线程所执行的字节码的行号指示器.由于JAVA是多线程的,因此每个线程都独立的程序计数器. 异常:没有规定任何OutOfMemeryError情况的 ...
- SPOJ_LCS2
和上个题目差不多,这次是找若干个串的LCS,若干<=10 . 做法上面也是类似的. 首先以第一个建立SAM,然后后面的串都在上面更新.每个串的更新是独立进行的,互不影响.对于同一状态,首先在同一 ...
- 使用rundll32.exe绕过应用程序白名单(多种方法)
0x00 前言 本文演示了白名单AppLocker bypass的最常见和最熟悉的技术.我们知道,出于安全原因,系统管理员添加组策略来限制本地用户的应用程序执行.在上一篇文章中,我们讨论了“ Wind ...
- 遇到问题----linux-----linux 打开文件数 too many open files 解决方法
在运行某些命令或者 tomcat等服务器持续运行 一段时间后可能遇到 too many open files. 出现这句提示的原因是程序打开的文件/socket连接数量超过系统设定值. 查看每个用 ...