单例的完整实现
2016-04-20 12:51
239 查看
1.单例模式的作用
1>可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
2>从而方便地控制了实例个数,并节约系统资源
2.单例模式的使用场合
* 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)
3.单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码
1>可以用宏判断是否为ARC环境
#if __has_feature(objc_arc)
// ARC
#else
// MRC
#endif
1>ARC环境下单例的两种实现
第一种:懒汉式生成单例
/**
static : 修饰变量
1> 修饰全局变量
* 全局变量的作用域仅限于当前文件内部
2> 修饰局部变量 :
* 局部变量的生命周期
跟 全局变量
类似
* 但是不能改变作用域
* 能保证局部变量永远只初始化1次,在程序运行过程中,永远只有1分内存
*/
在.m中保留一个全局的static的实例
static id _instance;
只允许内部访问。防止外部文件恶意篡改我的数据
如果不添加static 修饰_instance这个全局变量,在外部可以通过extern,在外部修改_instance的值
引用某个全局变量(并非定义)
extern id _instance;
_instance = nil;
extern是在整个项目中查找这个变量
1>在创建单例的是,如果是通过alloc,创建的对象,在底层都会调用
2>重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)
+ (id)allocWithZone:(struct
_NSZone *)zone,所以在创建对象的时候,我们要拦截创建信息
/**
* alloc方法内部会调用这个方法
*/
+ (id)allocWithZone:(struct
_NSZone *)zone
{
if (_instance ==
nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance ==
nil) { // 防止创建多次
_instance = [super
allocWithZone:zone];
}
}
}
return
_instance;
}
提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedMusicTool
{
if (_instance ==
nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance ==
nil) { // 防止创建多次
_instance = [[self
alloc] init];
}
}
}
return
_instance;
}
// copy 有可能会产生新的对象
// copy方法内部会调用- copyWithZone:
- (id)copyWithZone:(NSZone *)zone
{
return
_instance;
}
方式二:
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct
_NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super
allocWithZone:zone];
});
return
_instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self
alloc] init];
});
return
_instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return
_instace;
}
饿汉式创建单例的方式:
**
* 当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)
*/
+ (void)load
{
_instance = [[self
alloc] init];
}
+ (id)allocWithZone:(struct
_NSZone *)zone
{
if (_instance ==
nil) { // 防止创建多次
_instance = [super
allocWithZone:zone];
}
return
_instance;
}
+ (instancetype)sharedSoundTool
{
return
_instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return
_instance;
}
///**
// * 当第一次使用这个类的时候才会调用
// */
//+ (void)initialize
//{
// NSLog(@"HMSoundTool---initialize");
//}
非ARC环境下单例的实现:
1>非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)
2>实现内存管理方法
- (id)retain {
return self; }
- (NSUInteger)retainCount {
return 1; }
- (oneway void)release{}
- (id)autorelease {
return self; }
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct
_NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super
allocWithZone:zone];
});
return
_instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self
alloc] init];
});
return
_instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return
_instace;
}
- (oneway void)release { }
- (id)retain { return
self; }
- (NSUInteger)retainCount {
return 1;}
- (id)autorelease {
return self;}
简化单例模式:
// .h文件
#define HMSingletonH + (instancetype)sharedInstance;
// .m文件
#define HMSingletonM \
static id _instance; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)sharedInstance \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
//ARC与非ARC混编
//#if __has_feture(objc_arc)
//ARC编译
//#else
//非ARC编译
//#endif
第二种表现形式:
// .h文件
#define HMSingletonH(name) +(instancetype)shared##name;
// .m文件
#define HMSingletonM \
static id _instance; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
//ARC与非ARC混编
//#if __has_feture(objc_arc)
//ARC编译
//#else
//非ARC编译
//#endif
.h文件中
#import <Foundation/Foundation.h>
@interface HMMovieTool : NSObject
HMSingletonH(MovieTool)
@end
.m文件中
#import "HMMovieTool.h"
@implementation HMMovieTool
HMSingletonM(MovieTool)
@end
1>可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
2>从而方便地控制了实例个数,并节约系统资源
2.单例模式的使用场合
* 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)
3.单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码
1>可以用宏判断是否为ARC环境
#if __has_feature(objc_arc)
// ARC
#else
// MRC
#endif
1>ARC环境下单例的两种实现
第一种:懒汉式生成单例
/**
static : 修饰变量
1> 修饰全局变量
* 全局变量的作用域仅限于当前文件内部
2> 修饰局部变量 :
* 局部变量的生命周期
跟 全局变量
类似
* 但是不能改变作用域
* 能保证局部变量永远只初始化1次,在程序运行过程中,永远只有1分内存
*/
在.m中保留一个全局的static的实例
static id _instance;
只允许内部访问。防止外部文件恶意篡改我的数据
如果不添加static 修饰_instance这个全局变量,在外部可以通过extern,在外部修改_instance的值
引用某个全局变量(并非定义)
extern id _instance;
_instance = nil;
extern是在整个项目中查找这个变量
1>在创建单例的是,如果是通过alloc,创建的对象,在底层都会调用
2>重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)
+ (id)allocWithZone:(struct
_NSZone *)zone,所以在创建对象的时候,我们要拦截创建信息
/**
* alloc方法内部会调用这个方法
*/
+ (id)allocWithZone:(struct
_NSZone *)zone
{
if (_instance ==
nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance ==
nil) { // 防止创建多次
_instance = [super
allocWithZone:zone];
}
}
}
return
_instance;
}
提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedMusicTool
{
if (_instance ==
nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance ==
nil) { // 防止创建多次
_instance = [[self
alloc] init];
}
}
}
return
_instance;
}
// copy 有可能会产生新的对象
// copy方法内部会调用- copyWithZone:
- (id)copyWithZone:(NSZone *)zone
{
return
_instance;
}
方式二:
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct
_NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super
allocWithZone:zone];
});
return
_instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self
alloc] init];
});
return
_instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return
_instace;
}
饿汉式创建单例的方式:
**
* 当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)
*/
+ (void)load
{
_instance = [[self
alloc] init];
}
+ (id)allocWithZone:(struct
_NSZone *)zone
{
if (_instance ==
nil) { // 防止创建多次
_instance = [super
allocWithZone:zone];
}
return
_instance;
}
+ (instancetype)sharedSoundTool
{
return
_instance;
}
- (id)copyWithZone:(NSZone *)zone
{
return
_instance;
}
///**
// * 当第一次使用这个类的时候才会调用
// */
//+ (void)initialize
//{
// NSLog(@"HMSoundTool---initialize");
//}
非ARC环境下单例的实现:
1>非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)
2>实现内存管理方法
- (id)retain {
return self; }
- (NSUInteger)retainCount {
return 1; }
- (oneway void)release{}
- (id)autorelease {
return self; }
@implementation HMDataTool
// 用来保存唯一的单例对象
static id _instace;
+ (id)allocWithZone:(struct
_NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super
allocWithZone:zone];
});
return
_instace;
}
+ (instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self
alloc] init];
});
return
_instace;
}
- (id)copyWithZone:(NSZone *)zone
{
return
_instace;
}
- (oneway void)release { }
- (id)retain { return
self; }
- (NSUInteger)retainCount {
return 1;}
- (id)autorelease {
return self;}
简化单例模式:
// .h文件
#define HMSingletonH + (instancetype)sharedInstance;
// .m文件
#define HMSingletonM \
static id _instance; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)sharedInstance \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
//ARC与非ARC混编
//#if __has_feture(objc_arc)
//ARC编译
//#else
//非ARC编译
//#endif
第二种表现形式:
// .h文件
#define HMSingletonH(name) +(instancetype)shared##name;
// .m文件
#define HMSingletonM \
static id _instance; \
\
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
//ARC与非ARC混编
//#if __has_feture(objc_arc)
//ARC编译
//#else
//非ARC编译
//#endif
.h文件中
#import <Foundation/Foundation.h>
@interface HMMovieTool : NSObject
HMSingletonH(MovieTool)
@end
.m文件中
#import "HMMovieTool.h"
@implementation HMMovieTool
HMSingletonM(MovieTool)
@end
相关文章推荐
- 趣味整数-黑洞数
- 108. Convert Sorted Array to Binary Search Tree
- 持续集成(二)环境搭建篇—内网邮件server搭建
- Oracle 删除重复的记录,只保留一条
- 势篇
- 用java实现随机输出1个[e, f)的数字
- 用 git 下载 uboot 源码
- 36. Valid Sudoku
- 正则验证匹配中文姓名全部源字符串
- 使用VMware 安装Linux CentOS7
- 20160420-序列比对前的准备工作
- Timus 1291 Gear-wheels
- 对下一步方向的迷失
- Zabbix Agent 源码编译安装
- DrawerLayout的侧拉范围方法,
- zabbix弱口令批量检测
- jQuery基础
- LVS DR模式问题
- API json多层数据实体类封装(利用泛型技术)
- FFmpeg:'UINT64_C' was not declared in ths scope