什么是单例
单例模式:一种常见的软件设计模式,通过单例模式的方法创建的类在当前进程中只有一个实例。如:
UIApplication
NSNotificationCenter
NSUserDefault
单例模式的优点
1、单例可以保证系统中该类有且仅有一个实例,确保所有对象都访问这个唯一实例。
2、因为只有一个实例,减少了内存开发和系统的性能开销。
单例模式的缺点
1、可扩展性比较差。
2、实例一旦被创造,分配的空间只有在 App 结束之后才会被释放。
3、滥用导致不相关的类产生的耦合问题。
OC单例的实现方法
经典写法
@implementation YZSingleton
// static 全局的变量
// static 修饰的变量存储在静态存储区,只会在程序结束之后才释放
static YZSingleton *instance = nil;
+ (instancetype)sharedSingleton {
// 线程不安全
if (instance == nil) {
instance = [[self alloc] init];
}
return instance;
}
这种实现方式只适用于单线程,在多线程的情况下无法保证线程安全
线程同步
@implementation YZSingleton
// static 全局的变量
// static 修饰的变量存储在静态存储区,只会在程序结束之后才释放
static YZSingleton *instance = nil;
+ (instancetype)sharedSingleton {
// 线程同步保证线程安全
@synchronized (self) {
if (instance == nil) {
instance = [[self alloc] init];
}
return instance;
}
}
这种实现方式保证多线程下也只有一个线程能进入
GCD 写法
@implementation YZSingleton
// static 全局的变量
// static 修饰的变量存储在静态存储区,只会在程序结束之后才释放
static YZSingleton *instance = nil;
+ (instancetype)sharedSingleton {
// dispatch_once 本身就是线程安全
// dispatch_once 执行时间要比 @synchronized 快
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
+ (id)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[YZSingleton alloc] init];
});
return instance;
}
- (instancetype)copyWithZone:(NSZone *)zone {
// return [YZSingleton sharedSingleton];
return instance;
}
- (instancetype)mutableCopyWithZone:(NSZone *)zone {
// return [YZSingleton sharedSingleton];
return instance;
}
GCD 优化禁止外部调用
在.h 文件中禁止调用初始化方法
+ (instancetype)sharedSingleton;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
+ (instancetype)alloc NS_UNAVAILABLE;
- (id)copy NS_UNAVAILABLE;
- (id)mutableCopy NS_UNAVAILABLE;
.m 文件
@implementation YZSingleton
// static 全局的变量
// static 修饰的变量存储在静态存储区,只会在程序结束之后才释放
static YZSingleton *instance = nil;
+ (instancetype)sharedSingleton {
// dispatch_once 本身就是线程安全
// dispatch_once 执行时间要比 @synchronized 快
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
宏定义
#define YZ_SINGLETON_DEF(_type_) + (_type_ *)sharedSingleton; \
- (instancetype)init __attribute__((unavailable("请使用sharedSingleton"))); \
+ (instancetype)new __attribute__((unavailable("请使用sharedSingleton"))); \
+ (instancetype)alloc __attribute__((unavailable("请使用sharedSingleton"))); \
- (id)copy __attribute__((unavailable("请使用sharedSingleton"))); \
- (id)mutableCopy __attribute__((unavailable("请使用sharedSingleton"))); \
#define YZ_SINGLETON_IMP(_type_) + (instancetype)sharedSingleton { \
static _type_ *instance = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
instance = [[super alloc] init]; \
}); \
return instance; \
}
使用:
@interface YZMarcoSingleton : NSObject
YZ_SINGLETON_DEF(YZMarcoSingleton);
@end
@implementation YZMarcoSingleton
YZ_SINGLETON_IMP(YZMarcoSingleton);
@end
Swift单例的实现方法
class YZSwiftSingleton {
static let sharedSingleton = YZSwiftSingleton()
private init(){}
func foo() {
print("foo-")
}
}