GCD实现设计模式
在某个类里面实现GCD单粒设计模式
- 类的.h文件
@interface ZMJPerson : NSObject
+ (instancetype)sharedInstance;
@end
- 类的.m文件
// 实例变量,当前类
static id _instance;
// 重写allocWithZone方法
+ (instancetype)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;
}
宏定义封装GCD单粒设计模式(1)
- 将实现单粒设计模式的代码放到宏定义里面,并且专门搞个.h文件存储该宏定义,使用的之后直接导入头文件即可,不必在每个类中实现单粒设计模式
- 注意:每行结尾需要添加\
// .h文件
#define ZMJSingletonH + (instancetype)sharedInstance;
// .m文件
#define ZMJSingletonM \
static id _instance;\
\
+ (instancetype)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;\
}
宏定义封装GCD单粒设计模式(2)
- 如果希望每次有特有的类名,可以使用##拼接宏
// .h文件
#define ZMJSingletonH(name) + (instancetype)shared##name;
// .m文件
#define ZMJSingletonM(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;\
}
非GCD实现设计模式
就介绍怎么使用,其它宏定义保存跟上面一样
ZMJPerson类的.h文件
@interface ZMJPerson : NSObject
+ (instancetype)sharedInstance;
@end
- ZMJPerson类的.h文件
static id _instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
// 同步锁,防止多线程同时进入
@synchronized(self){
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
}
return _instance;
}
+ (instancetype)sharedInstance{
@synchronized(self){
if (_instance == nil) {
_instance = [[self alloc] init];
}
}
return _instance;
}
- (id)copyWithZone:(NSZone *)zone{
return _instance;
}
注意点
- 一般当两个类有相同的属性和方法,我们会考虑将相同的部分抽取出来,封装到父类,让这两个类成为它的子类,但单粒设计模式不可以这样做;
- 因为start修饰的变量在内存中只有一份内存,如果单粒设计模式采用继承的方式的话,所有的类共享一份内存;
- 其实我们只要保证每一个类的对象只有一份内存即可