顾名思义,单例模式即在整个程序的运行当中,一个类只有一个实例化的对象。它运用的场合是在应用程序运行时,有多个地方需要用到一个相同的对象。
一个类一个实例化对象即该类实例化对象时,在内存分配的时候,单例对象的内存空间只会被分配一次。在iOS开发中,实例化的对象进行内存分配时是在类方法+ (instancetype)allocWithZone:(struct _NSZone *)zone中进行的。因此在单例对象进行实例化时,需要重写该方法。
在ARC机制中,单例实现的步骤主要如下:
1.在类的内部提供一个static修饰的全局变量
2.提供一个类方法,方便外界访问
3.重写+allocWithZone方法,保证只为单例对象分配一次内存空间
具体代码如下:
// 单例模式
static PGXPerson *_instance;
// 单例模式实例化对象时,需要重写allocWithZone类方法
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
// // 1.使用互斥锁
// @synchronized (self) {
// if (!_instance) {
// _instance = [super allocWithZone:zone];
// }
// }
//
// 2.使用一次性代码
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
// 实例化对象方法,访苹果官方的单例对象实例化方法 命名方式为share+类名或者default+类名
+ (instancetype)sharedPerson
{
return [[self alloc] init];
}
为了使对象在初始化时,只分配一次内存空间,重写allocWithZone方法时,使用GCD中的一次性代码或者对代码进行加锁处理。
如果在一个项目中需要多个单例对象,那么我们可以在项目中使用宏定义一个single.h的头文件,具体代码如下:
#define singleH(name) + (instancetype)shared##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)shared##name\
{\
return [[self alloc] init];\
}
#else
#endif
以上代码中使用的是带参数的宏定义,其中##name部分是由传入的参数替换。由于ARC与MRC机制下单例模式的写法不一样,在宏定义中使用了条件编译,现阶段iOS开发中极少使用MRC,因此MRC模式下的单例模式我没有写。
https://github.com/SevenDK/singleton,这是我的github单例模式项目库地址,希望对各位有用。