單例的應用十分普遍,單例模式使一個類只有一個實例。
一、ARC中實現單例
tips:
@implementation XNShareTool
/**
步驟:
1.一個靜態變量_inastance
2.重寫allocWithZone, 在裏面用dispatch_once, 並調用super allocWithZone
3.自定義一個sharedXX, 用來獲取單例. 在裏面也調用dispatch_once, 實例化_instance
-----------可選------------
4.如果要支持copy. 則(先遵守NSCopying協議)重寫copyWithZone, 直接返回_instance即可.
*/
/**第1步: 存儲唯一實例*/
static XNShareTool *_instance;
/**第2步: 分配內存孔家時都會調用這個方法. 保證分配內存alloc時都相同*/
+(id)allocWithZone:(struct _NSZone *)zone{
//調用dispatch_once保證在多線程中也只被實例化一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
/**第3步: 保證init初始化時都相同*/
+(instancetype)sharedTool{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[XNShareTool alloc] init];
});
return _instance;
}
/**第4步: 保證copy時都相同*/
-(id)copyWithZone:(NSZone *)zone{
return _instance;
}
@end
測試代碼如下(打印單例對象的地址都相同):
-(void)viewDidLoad{
//實例化一個類的幾種方法. 單例就是要保證實例化出來的類是同一個類
//1.alloc init方法. 一般不這麼來調用單例.
XNShareTool *t1 = [[XNShareTool alloc] init];
XNShareTool *t2 = [[XNShareTool alloc] init];
//2.類方法
XNShareTool *t3 = [XNShareTool sharedTool];
//3.copy
XNShareTool *t4 = [t3 copy];
NSLog(@"%@ %@ %@ %@", t1, t2, t3, t4);
}
#import "XNShareTool.h"
@implementation XNShareTool
static XNShareTool *_instance;
+ (id)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
+ (instancetype)sharedTool {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[XNShareTool alloc] init];
});
return _instance;
}
- (id)copyWithZone:(NSZone *)zone {
return _instance;
}
#pragma mark - MRC中需要覆蓋的方法
//不需要計數器+1
- (id)retain {
return self;
}
//不需要. 堆區的對象才需要
- (id)autorelease {
return self;
}
//不需要
- (oneway void)release {
}
//不需要計數器個數. 直接返回最大無符號整數
- (NSUInteger)retainCount {
return UINT_MAX; //參照常量區字符串的retainCount
}
@end
三、ARC與MRC的整合
#if !__has_feature(objc_arc)
MRC中內存管理的方法放在這個地方
#endif
代碼如下:
//=============================ARC/MRC整合=======================================
#pragma mark - MRC中需要覆蓋的方法, ARC與MRC的整合
#if !__has_feature(objc_arc)
- (id)retain {
return self;
}
- (id)autorelease {
return self;
}
- (oneway void)release {
}
- (NSUInteger)retainCount {
return UINT_MAX;
}
#endif
//============================================================================
轉載請註明出處:http://blog.csdn.net/xn4545945