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