iOS单例初步理解
在iOS开发中,系统自带的框架中使用了很多单例,非常方便用户(开发者,使用比如[NSApplication sharedApplication] 等),在实际的开发中,有时候也需要设计单例对象,为保证每次获取的对象都为同一个对象。
在iOS开发中创建单例具体步骤:
1.提供一个类方法:+ (instancetype)sharedXXXX;
2.创建一个全局静态变量static id _instance;
3.重写allocWithZone
4.重写copyWithZone
特举例子如下:
@interface MusicTool : NSObject
+ (instancetype)sharedMusicTool;
@end
static id _instance; // 全局变量
/**
* alloc方法内部会调用allocWithZone
*/
+ (id)allocWithZone:(struct _NSZone *)zone {
if (_instance == nil) {
@synchronized(self) {
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}
/**
* 重写copy方法,防止copy出错
*/
- (instancetype)copyWithZone:(NSZone *)zone {
return _instance;
}
- (instancetype)sharedMusicTool {
if (_instance == nil) {
@synchronized(self) {
if (_instance == nil) {
_instance = [[self alloc] init];
}
}
}
return _instance;
}
第二种使用GCD创建单例方法
@interface DataTool : NSObject
+ (instancetype)shareDataTool;
@end
static id _instance;
+ (id)allocWithZone:(struct _NSZone *)zone {
if (_instance == nil) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
}
return _instance;
}
- (instancetype)copyWithZone:(NSZone *)zone {
return _instance;
}
- (instancetype)shareDataTool {
if (_instance == nil) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc]init];
});
}
return _instance;
}
第三种使用饿汉模式
@interface SoundTool : NSObject - (instancetype)sharedSoundTool;
@end
static id _instance;
+ (void)load {
_instance = [[self alloc]init];
}
(instancetype)allocWithZone:(struct _NSZone *)zone {
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
return _instance;
}(instancetype)sharedSoundTool {
return _instance;
}(instancetype)copyWithZone:(NSZone *)zone {
return _instance;
}
为保证兼容MRC还需要重写
static id _instace;
(id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}(instancetype)sharedDataTool
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}(id)copyWithZone:(NSZone *)zone
{
return _instace;
}(oneway void)release { } //重写release
- (id)retain { return self; } //重写retain
- (NSUInteger)retainCount { return 1;} //重写retainCount
- (id)autorelease { return self;} //重写autorelease