前言
1、GCD 方式创建
-
1.1 GCD 创建方式 1
- 下面的创建方式保证了用户除了可以通过 sharedManager 方法创建实例外,还可以通过 alloc、copy 方法创建不同的实例。
// SingleClass.h
#import <Foundation/Foundation.h>
@property (nonatomic, copy)NSString *text;
// 声明单例的类方法
+ (instancetype)sharedManager;
@end
// SingleClass.m
#import "SingleClass.h"
@implementation SingleClass
+ (instancetype)sharedManager{
// 创建静态单例类对象
static id instance = nil;
// 执行且在整个程序的声明周期中,仅执行一次某一个 block 对象
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 初始化单例类对象
instance = [[self alloc] init];
});
return instance;
}
@end
// 单例类对象的调用
// 创建单例类对象
SingleClass *single1 = [SingleClass sharedManager];
// 赋值
single1.text = @"Hello World";
// 取值
NSString *string1 = [SingleClass sharedManager].text;
-
1.2 GCD 创建方式 2
- 下面的创建方式保证了用户不管是通过 sharedManager 方法,还是 alloc、copy 方法得到的实例都是一样的。
static id instance = nil;
+ (instancetype)sharedManager {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [super allocWithZone:zone];
});
return instance;
}
- (id)copyWithZone:(NSZone *)zone {
return instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
return instance;
}
2、互斥锁方式创建
- 互斥锁会影响性能,所以最好还是使用 GCD 方式创建单例。
-
2.1 互斥锁 创建方式 1
- 下面的创建方式保证了用户除了可以通过 sharedManager 方法创建实例外,还可以通过 alloc、copy 方法创建不同的实例。
// SingleClass.h
#import <Foundation/Foundation.h>
@property (nonatomic, copy)NSString *text;
// 声明单例的类方法
+ (instancetype)defaultManager;
@end
// SingleClass.m
#import "SingleClass.h"
@implementation SingleClass
+ (instancetype)defaultManager{
// 创建静态单例类对象
static id instance = nil;
// @synchronized 同一时刻,只能有一个线程来执行 {} 中的代码
@synchronized(self){
if (!instance) {
// 初始化单例类对象
instance = [[self alloc] init];
}
}
return instance;
}
@end
// 单例类对象的调用
// 创建单例类对象
SingleClass *single2 = [SingleClass defaultManager];
// 赋值
single2.text = @"Hello World";
// 取值
NSString *string2 = [SingleClass defaultManager].text;
-
2.2 互斥锁 创建方式 2
- 下面的创建方式保证了用户不管是通过 sharedManager 方法,还是 alloc、copy 方法得到的实例都是一样的。
static id instance = nil;
+ (instancetype)defaultManager {
@synchronized(self) {
if (instance == nil) {
instance = [[self alloc] init];
}
}
return instance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
@synchronized(self) {
if (instance == nil) {
instance = [super allocWithZone:zone];
}
}
return instance;
}
- (id)copyWithZone:(NSZone *)zone {
return instance;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
return instance;
}
3、快速创建
/*
使用示例:
GCTool.h文件
#import <Foundation/Foundation.h>
@interface GCTool : NSObject
SingletonH(Instance)
@end
GCTool.m文件
#import "GCTool.h"
@implementation GCTool
SingletonM(Instance)
@end
// 宏定义简化
#define GC_Tool [GCTool shareInstance]
// 有时候需要重置单例
[GC_Tool resetInstance];
*/
#pragma mark - 快速实现单例设计模式
/** 单例模式 .h文件的实现:包含单粒常规工厂方法 shareInstance 与 重置单粒方法 resetInstance*/
#define SingletonH(Instance) + (instancetype)share##Instance;- (void)resetInstance;
/** 单例模式 .m文件的实现:包含单粒常规工厂方法 shareInstance 与 重置单粒方法 resetInstance */
// 注意⚠️:暂时不支持MRC情况下的 重置单粒方法 resetInstance
#if __has_feature(objc_arc) // 是ARC
#define SingletonM(Instance) \
static id _gc_##Instance = nil; \
static dispatch_once_t gc_Token##Instance; \
- (id)init \
{ \
dispatch_once(&gc_Token##Instance, ^{ \
_gc_##Instance = [super init]; \
}); \
return _gc_##Instance; \
} \
\
+ (instancetype)share##Instance \
{ \
return [[self alloc] init]; \
}\
- (void)resetInstance {\
gc_Token##Instance = 0;\
_gc_##Instance = nil;\
}
#else // 不是ARC
#define SingletonM(Instance); \
static id _gc_##Instance = nil; \
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
if (_gc_##Instance == nil) { \
static dispatch_once_t gc_Token##Instance; \
dispatch_once(&gc_Token##Instance, ^{ \
_gc_##Instance = [super allocWithZone:zone]; \
}); \
} \
return _gc_##Instance; \
} \
\
- (id)init \
{ \
static dispatch_once_t gc_Token##Instance; \
dispatch_once(&gc_Token##Instance, ^{ \
_gc_##Instance = [super init]; \
}); \
return _gc_##Instance; \
} \
\
+ (instancetype)share##Instance \
{ \
return [[self alloc] init]; \
} \
\
- (oneway void)release \
{ \
\
} \
\
- (id)retain \
{ \
return self; \
} \
\
- (NSUInteger)retainCount \
{ \
return 1; \
} \
+ (id)copyWithZone:(struct _NSZone *)zone \
{ \
return _gc_##Instance; \
} \
\
+ (id)mutableCopyWithZone:(struct _NSZone *)zone \
{ \
return _gc_##Instance; \
}
#endif
/** 单例模式 .m文件的实现:包含单粒常规工厂方法 shareInstance 与 重置单粒方法 resetInstance */
// 注意⚠️:暂时不支持MRC情况下的 重置单粒方法 resetInstance
/** 单例模式 .m文件的实现 InitData */
#if __has_feature(objc_arc) // 是ARC
#define SingletonM_Init(Instance) \
static id _gc_##Instance = nil; \
static dispatch_once_t gc_Token##Instance; \
- (id)init \
{ \
dispatch_once(&gc_Token##Instance, ^{ \
_gc_##Instance = [super init]; \
[self InitData];\
}); \
return _gc_##Instance; \
} \
\
+ (instancetype)share##Instance \
{ \
return [[self alloc] init]; \
}\
- (void)resetInstance {\
gc_Token##Instance = 0;\
_gc_##Instance = nil;\
}
#else // 不是ARC
#define SingletonM(Instance); \
static id _gc_##Instance = nil; \
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
if (_gc_##Instance == nil) { \
static dispatch_once_t gc_Token##Instance; \
dispatch_once(&gc_Token##Instance, ^{ \
_gc_##Instance = [super allocWithZone:zone]; \
}); \
} \
return _gc_##Instance; \
} \
\
- (id)init \
{ \
static dispatch_once_t gc_Token##Instance; \
dispatch_once(&gc_Token##Instance, ^{ \
_gc_##Instance = [super init]; \
}); \
return _gc_##Instance; \
} \
\
+ (instancetype)share##Instance \
{ \
return [[self alloc] init]; \
} \
\
- (oneway void)release \
{ \
\
} \
\
- (id)retain \
{ \
return self; \
} \
\
- (NSUInteger)retainCount \
{ \
return 1; \
} \
+ (id)copyWithZone:(struct _NSZone *)zone \
{ \
return _gc_##Instance; \
} \
\
+ (id)mutableCopyWithZone:(struct _NSZone *)zone \
{ \
return _gc_##Instance; \
}
#endif