一、什么是单例:
单例:在内存中只有唯一的实例,并且提供一个全局的访问方法!
单例的好处:可以实现同一份资源共享。
最常用的应用实例:音乐播放!
二、单例设计:非全部封死,提供两个创建对象的方式
(1)可以选择使用类方法,直接创建一个单例对象
(2)也可以选择使用其他方式,如alloc、init方式,创建非单例对象
在单例类的.m文件中:
+(instancetype)shareManager
{
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc]init];
});
return instance;
}
三、单例设计:全部封死,不论怎么创建,产生的都是单例对象
1、在ARC环境下,单例类.m文件:
static id _instance;
@implementation HMAccount
//提供一个类方法,快速创建单例对象
+(instancetype)shareAccount
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc]init];
});
return _instance;
}
-(instancetype)init
{
if (self = [super init]) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//初始化代码
});
}
return self;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
2、在MRC(非ARC)环境下,单例类.m文件:
static id _instance;
@implementation HMAccount
/**
* 实现自定义方法,内部创建对象
*/
+ (instancetype)shareAccount
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc]init];
});
return _instance;
}
/**
* 重写init方法,保证初始化资源操作只做一次
*/
-(instancetype)init
{
if (self = [super init]) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//加载资源,子控件等
});
}
return self;
}
/**
* 重写alloc方法,保证对象只创建一个,地址唯一
*/
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
/**
* 重写copy方法,内部创建对象
*/
+ (id)copyWithZone:(struct _NSZone *)zone
{
return _instance;
}
/**
* 重写release方法,不允许释放对象
*/
-(oneway void)release
{
}
/**
* 重写release方法,不允许释放对象
*/
-(instancetype)autorelease
{
return _instance;
}
/**
* 重写retain方法,不允许对象计数器+1
*/
-(instancetype)retain
{
return _instance;
}
/**
* 重写retain方法,不允许对象计数器+1
*/
-(NSUInteger)retainCount
{
return 1;
}
四、高效编程 —- 使用宏封装单例模型(以ARC下,全部封死的情况为例)
(1)新建一个.h文件,定义单例宏
#define singleton_h(name) +(instancetype)share##name;
#define singleton_m(name)\
static id _instance;\
+(instancetype)share##name\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [[self alloc]init];\
});\
return _instance;\
}\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}
(2)使用
在需要设计成单例的类中:(Account类)
—》 .h文件中:singleton_h(Account)
—》 .m文件中:singleton_m(Account)
五、总结
1、在实际开发中根据实际需求选择是否需要全部封死
2、个人建议:使用第一种方法,不要全部封死,提供一个快速创建单例对象的方法就好了。
这样设计也是仿照苹果单例的设计模式,例如:
UIApplication *app = [UIApplicationsharedApplication];
UIApplication *app1 = [[UIApplicationalloc]init];