1.目的:保证程序在运行过程中,一个类只有一个实例,且易于调用,只需要创建初始化一次,共享一份资源
2.新创建一个类,如果对这个类多次初始化,便会得到多个类对象,分配多个内存空间,如果有‘初始化多次这个类,但是需要获得同一个对象’的需求,就要使用到单例设计模式实现。
3.要实现每次初始化都得到同一个对象,就需要对alloc方法进行重写。但是不管是alloc还是allocWithZone最终都是调用的allocWithZone方法,所以只需要对allocWithZone方法进行重写就行了。
4.代码实现:创建一个ETPerson类,实现NSCopying协议
ETPerson.h
+ (instancetype)sharedPerson; //写一个类方法,进行类的初始化
ETPerson.m
static XMGPerson *_person;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{ //重写allocWithZone方法,需要先调用父类的方法实现,赋值给类对象,使用GCD一次性函数,保证程序运行期间只调用一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone]; //不能直接return,需要调用父类方法,得到值,否则是空值
});
return _person;
}
+ (instancetype)sharedPerson
{ //初始化,调用allocWithZone方法
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [[self alloc] init];
});
return _person;
}
- (id)copyWithZone:(NSZone *)zone
{ //保证类对象进行复制时,得到的也是同一个对象,同一块内存地址,因为此时已经有了对象,有了值,所以直接return即可
return _person;
}
5.单例宏:因为不论对几个类设计为单例,重写的方法和步骤都是一样的,所以可以抽出成宏在工程中调用,简单方便。
Macro.h
// .h文件
#define ETSingletonH + (instancetype)sharedInstance;
// .m文件
#define ETSingletonM \
static id _instace; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [super allocWithZone:zone]; \
}); \
return _instace; \
} \
+ (instancetype)sharedInstance \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instace = [[self alloc] init]; \
}); \
return _instace; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instace; \
}
定义宏,代码需要写在一行,才不会报错,对于多行代码的宏定义,需要在每行代码的后面加一个\,这样下一行代码就会被识别到上一行,就不会报错了。
以上的宏定义的类方法名,任何一个类调用,显示都是一样的,如果想实现不同类实现单例时,调用类方法名也显示不同,进行区分时,可以使用下面宏定义:
6.自定义类方法名的宏定义
// .h文件
#define ETSingletonH(name) + (instancetype)shared##name;
// .m文件
#define ETSingletonM(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 \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
- (id)copyWithZone:(NSZone *)zone \
{ \
return _instance; \
}
--对.h文件宏定义做个解释:
#define ETSingletonH(name) + (instancetype)shared##name;
(name)调用者传入的自定义方法名;##是连接符 -- ##name会被替换为调用者传入的自定义方法名。
网友评论