ARC环境下实现单例模式
@interface Test:NSObject<NSCopying,NSMutableCopying>
+(instancetype)default;
@end;
@implementation Test
static Test *instance;
//1.重写allocWithZone
+(instancetype) allocWithZone:(struct _NSZone *)zone{
//方法一 加互斥锁 解决多线程访问安全问题
/*@synchronized(self){
if(_instance==nil){
_instance = [super allocWithZone:zone];
}
}*/
//方法二 该方法本身就是线程安全的
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
//2.提供类方法
+(instancetype)default{
return [[self alloc] init];
}
//3.copy
//调用方法 Test t2 = [t1 copy] | [t1 mutableCopy];
-(id) copyWithZone:(NSZone *)zone{
return _instance;
}
-(id) mutableCopyWithZone:(NSZone *)zone{
return _instance;
}
@end
MRC环境下实现单例模式
MRC环境下的单例模式大致与ARC环境下相同,只不过要重写三个方法,在这里我们为了让这段代码即适用于ARC也适用于MRC,我们在代码中加入条件判断#if。
@interface Test:NSObject<NSCopying,NSMutableCopying>
+(instancetype)default;
@end;
@implementation Test
static Test *instance;
//1.重写allocWithZone
+(instancetype) allocWithZone:(struct _NSZone *)zone{
//方法一 加互斥锁 解决多线程访问安全问题
/*@synchronized(self){
if(_instance==nil){
_instance = [super allocWithZone:zone];
}
}*/
//方法二 该方法本身就是线程安全的
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
//2.提供类方法
+(instancetype)default{
return [[self alloc] init];
}
//3.copy
//调用方法 Test t2 = [t1 copy] | [t1 mutableCopy];
-(id) copyWithZone:(NSZone *)zone{
return _instance;
}
-(id) mutableCopyWithZone:(NSZone *)zone{
return _instance;
}
#if __has_feature(objc_arc)
//ARC 不做操作
#else
//MRC
-(oneway void)release{
}
-(instancetype)retain{
return _instance;
}
//约定俗成 当实现单例后返回最大值
-(NSUInteger)retainCount{
return MAXFLOAT;
}
#endif
@end
抽取代码,封装单例(单例宏)Single.h
为了使默认构造方法能够变成default+类名的形式,所以在使用宏时我们将类名作为参数传给单例宏。
#if __has_feature(objc_arc)
//ARC
#define SingleH(name) +(instancetype) default##name;
#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)default##name{\
return [[self alloc] init];\
}\
\
-(id) copyWithZone:(NSZone *)zone{\
return _instance;\
}\
\
-(id) mutableCopyWithZone:(NSZone *)zone{\
return _instance;\
}
#else
//MRC
#define SingleH(name) +(instancetype) default##name;
#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)default##name{\
return [[self alloc] init];\
}\
\
-(id) copyWithZone:(NSZone *)zone{\
return _instance;\
}\
\
-(id) mutableCopyWithZone:(NSZone *)zone{\
return _instance;\
}\
-(oneway void)release{\
}\
\
-(instancetype)retain{\
return _instance;\
}\
\
-(NSUInteger)retainCount{\
return MAXFLOAT;\
}
#endif
使用封装好的单例宏
#import "Single.h"
@interface Test:NSObject<NSCopying,NSMutableCopying>
SingleH(Test)
@end
@implementation Test
SingleM(Test)
@end