在iOS 中,一般情况下会提供一个单例,供整个App中调用,通用名称为 [类名 sharedXXX].
在多线程的情况下,要保证线程安全或者数据安全,需要加入dispatch_once.
static id _instance;
+ (instancetype) sharedPerson{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc]init];
});
return _instance;
}
此时,通过【类名 sharedxxx】就可以获得这个单例对象。
同时,如果不想使用单例对象,想还可以通过alloc init的方法创建一个新的对象。
如果使整个App 中无论通过何种方式,都只能回创建出同一个对象,需要重写allocWithZone、copy,mutableCopy方法。
+ (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;
}
以上还不够!以上只是在ARC环境下的单例。如果在MRC下,还需要重写retain release autoRelease retainCount方法
- (instancetype)retain{
return _instance;
}
-(NSUInteger)retainCount{
return 1;
}
- (oneway void)release{
}
- (instancetype)autorelease{
return _instance;
}
为了保证以上代码在ARC和MRC下都能正常使用,需要加入条件编译
# if __has_feature(objc_arc)
//ARC下需要的执行的
# else
//MRC下需要执行的
# endif
重构::
重新创建一个Singleton.h文件.
#define Singleton_h(name) +(instancetype) shared##name;
# if __has_feature(objc_arc)
#define Singleton_m(name) static id _instance;\
\
+ (instancetype) shared##name{\
\
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;\
}
# else
#define Singleton_m(name) static id _instance;\
\
static id _instance;\
\
+ (instancetype) shared##name{\
\
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;\
}\
\
- (instancetype)retain{\
\
return _instance;\
}\
\
-(NSUInteger)retainCount{\
\
return 1;\
}\
\
- (oneway void)release{\
\
}\
\
- (instancetype)autorelease{\
\
return _instance;\
}
# endif
在类的.h文件中,导入头文件,再使用下面一句代码
#import "Singleton.h"
Singleton_h(类名)
在类的.m文件中,使用一句:
Singleton_m(类名)
就可以创建了一个单例。同过[类名 sharedXXX]访问这个单例
注意:通常情况下,不要覆盖allocWithZone、copyWithZone等方法,直接使用dispatch_once那个就行。