MRC下单例模式的内存问题与ARC实现
单例模式保证一个类只能拥有一个静态的实例,类负责创建与维护这个实例,并提供一个统一的静态(类方法)访问方式,并封锁了这个类外部的代码对这个类对象的创建。
.h文件:
#import <Foundation/Foundation.h> @interface Singleton : NSObject
@property (nonatomic, copy) NSString *name;
+ (Singleton *) sharedInstance;
@end
这里定义了一个类方法来获取单例对象的实例。
.m文件则比较复杂,首先要负责这个对象的创建:
#import "Singleton.h" @implementation Singleton static Singleton *_sharedInstance = nil;
+ (Singleton *) sharedInstance {
if (_sharedInstance == nil) {
_sharedInstance = [[super allocWithZone:nil] init];
}
return _sharedInstance;
} +(id)allocWithZone:(struct _NSZone *)zone {
return [[self sharedInstance] retain];
}
这里令人费解的是红字部分,为什么不直接alloc一个Singletone呢?
其实allocWithZone:nil就等价于alloc,只是这里alloc的是父类NSObject,这样做目的是把子类Singleton的allocWithZone拆解出去,拆解出来是为了复写。
之所以要复写,是为了堵住内存分配的漏洞,因为除了+sharedInstance方法之外,用户还可能在外部程序当中alloc一个Singleton对象,而OC语言并不支持java/C#当中的将构造函数私有化。
所以,子类复写allocWithZone的目的就显而易见、无需多言了。
到这里还没有结束,还需要堵住其他内存管理的漏洞,一是保证直接alloc的结果和使用sharedInstance方法的效果一样,二是令release无效:
-(id)copyWithZone:(NSZone *)zone {
return self;
} -(id)init {
if (_sharedInstance) {
return _sharedInstance;
}
self = [super init];
return self;
} - (id)retain {
return self;
} -(void)release {
// Do nothing
} -(id)autorelease {
return self;
} -(NSUInteger)retainCount {
return NSUIntegerMax;
}
这样就形成了一个中规中矩的、满足内存管理的单例模式,代码显得十分啰嗦,本质原因在于OC对private支持的不好,导致我们做了很多额外工作。
上面的代码不是线程安全的,如果需要保证单例对象的线程安全性,则需要写同步锁代码。
ARC下的单例相对简单:
+ (id)sharedInstance
{
static dispatch_once_t pred = ;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
更有甚者搞了一个宏:http://lukeredpath.co.uk/blog/2011/07/01/a-note-on-objective-c-singletons/
MRC下单例模式的内存问题与ARC实现的更多相关文章
- iOS: ARC & MRC下string内存管理策略探究
ARC & MRC下string内存管理策略探究 前两天跟同事争论一个关于NSString执行copy操作以后是否会发生变化,两个人整了半天,最后写代码验证了一下,发现原来NSString操作 ...
- 1.ARC下是否有内存溢出等问题 2.@property参数 3.#import和@class的区别
1.ARC下是否有内存溢出等问题? 答案:必须要担心啊,ARC也不是万能的.答案:必须要担心啊,ARC也不是万能的.这里主要是涉及到集合类的数据类型 比如数组,我们定义了一个可变数组muarr1, ...
- OC的内存管理(二)ARC
指针: 指向内存的地址指针变量 存放地址的变量指针变量值 变量中存放的值(地址值)指针变量指向的内存单元值 内存地址指向的值1):强指针:默认的情况下,所有的指针都是强指针,关键字strong ):弱 ...
- linux 下 取进程占用内存(MEM)最高的前10个进程
# linux 下 取进程占用 cpu 最高的前10个进程ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head # linux 下 取进程占用内存 ...
- Linux 下增大tomcat内存
我的服务器的配置: # OS specific support. $var _must_ be set to either true or false. JAVA_OPTS="-Xms10 ...
- 32位Windows7上8G内存使用感受+xp 32位下使用8G内存 (转)
32位Windows7上8G内存使用感受+xp 32位下使用8G内存 博客分类: Windows XPWindowsIE企业应用软件测试 我推荐做开发的朋友:赶快加入8G的行列吧....呵呵..超爽 ...
- (转)Linux下tomcat JVM内存设置步骤
java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemoryError: Java heap space -------------- ...
- [转帖]linux下CPU、内存、IO、网络的压力测试,硬盘读写速度测试,Linux三个系统资源监控工具
linux下CPU.内存.IO.网络的压力测试,硬盘读写速度测试,Linux三个系统资源监控工具 https://blog.51cto.com/hao360/1587165 linux_python关 ...
- iOS下单例模式实现(一)(objective-c arc gcd)
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 这里主要介绍下在arc下,利用gcd实现单例. 第一步:声明一个静态实例 static SoundTool *_instan ...
随机推荐
- php随笔1-php图片处理
php图片处理的知识内容 upload_image.php: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN ...
- redis的内部实现机制
一 理论基础 redis
- hdu 5652 India and China Origins 二分+bfs
题目链接 给一个图, 由01组成, 1不能走. 给q个操作, 每个操作将一个点变为1, 问至少多少个操作之后, 图的上方和下方不联通. 二分操作, 然后bfs判联通就好了. #include < ...
- vb socket的使用
说明:原本在 csdn 博客 写博客的,因为使用的移动宽带,csdn的 博客无法访问,所以先暂时到博客园写博客了 有能解决移动宽带 有部分网站不能访问的问题,请联系我,QQ 809775607 /** ...
- Werkzeug源码阅读笔记(三)
这次主要讲下werkzeug中的Local. 源码在werkzeug/local.py Thread Local 在Python中,状态是保存在对象中.Thread Local是一种特殊的对象,它是对 ...
- 异构数据源海量数据交换工具-Taobao DataX 下载和使用
DataX介绍 DataX是一个在异构的数据库/文件系统之间高速交换数据的工具,实现了在任意的数据处理系统(RDBMS/Hdfs/Local filesystem)之间的数据交换. 目前成熟的数据导入 ...
- VC6.0调试大全
VC调试方法大全 一.调试基础 调试快捷键 F5: 开始调试 Shift+F5: 停止调试 F10: 调试到下一句,这里是单步跟踪 F11: 调试到下一句,跟进函数内部 Shift+F11: ...
- JAVA基础 (二)反射 深入解析反射机制
在谈论到反射这个问题时,你是否有例如以下疑问? 不管是在.NET还是Java中反射的原理和机制是一样的,理解了一种还有一种就能够迎刃而解,想要理解反射首先须要了解底层的一些概念和执行.理解了反射有助于 ...
- Rabbit and Grass(杭电1849)(尼姆博弈)
Rabbit and Grass Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- C#高级编程三十天----泛型结构,泛型方法,泛型托付
泛型结构 泛型结构和泛型类差点儿是一直的,仅仅是泛型结构没有继承的特性..NET平台提供的一个泛型结构是(可空类型)Nullablle<T>.可空类型的引入,主要是为了解决数据库语言中的数 ...