1. 简介
本文借鉴了一位大神的文章,大神。
单例的作用是在整个程序中,一个类只有一个实例,常见于播放器,管理类。
优点:
单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
单例模式因为类控制了实例化过程,所以类可以更加灵活修改实例化过程。
缺点:
单例对象一旦建立,对象指针是保存在静态区的,单例对象在堆中分配的内存空间,会在应用程序终止后才会被释放。
单例类无法继承,因此很难进行类的扩展。
单例不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
2. 基本使用
首先,创建一个Singleton类
然后声明一个静态变量,并重写代理的初始化方法。
static Singleton *singleton;
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (singleton == nil) {
singleton = [[Singleton alloc] init];
}
});
return singleton;
}
然后命名为share开头的方法,这样单例的初始化方法就创建完了
+ (instancetype)shareSingleton
{
return [[self alloc] init];
}
当然,以下两个方法也需要重写,因为这两个方法也会创建新实例变量
-(id)copyWithZone:(NSZone *)zone
{
return singleton;
}
-(id)mutableCopyWithZone:(NSZone *)zone
{
return singleton;
}
3. 最后附上MRC和ARC共用的单例宏定义。
#define singleH(name) +(instancetype)share##name;
#if __has_feature(objc_arc)
#define singleM(name) static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}\
\
+(instancetype)share##name\
{\
return [[self alloc]init];\
}\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}
#else
#define singleM static id _instance;\
+(instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [super allocWithZone:zone];\
});\
return _instance;\
}\
\
+(instancetype)shareTools\
{\
return [[self alloc]init];\
}\
-(id)copyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
-(id)mutableCopyWithZone:(NSZone *)zone\
{\
return _instance;\
}\
-(oneway void)release\
{\
}\
\
-(instancetype)retain\
{\
return _instance;\
}\
\
-(NSUInteger)retainCount\
{\
return MAXFLOAT;\
}
#endif
结语:限于水平,本文只写了一些基本用法和注意事项,如果文中存在错误请指出,我会及时修改。