制造单例对象的步骤,例如做1个httpTool的单例
1. 必须有一个全局实例
static HttpTool *_instance;
2.提供生成单例对象的类方法
+ (id)sharedHttpTool
{
if(_instance == nil){
_instance = [[self alloc] init];
}
return _instance;
}
3.如果有人使用 [ [ httpTool alloc ] init ] 去生成实例,依然会生成新的实例,所以需要拦截alloc-init方法,alloc-init方法内部会调用allocWithZone方法,重写此方法即可实现拦截
+ (id)allocWithZone:(NSZone *)zone
{
// 敲dispatch_once有智能提醒
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
至此ARC项目中单例就做好了.
4. 如果是MRC项目
4.1 为了防止其他人把单例对象释放调,必须拦截release方法
- (oneway void)release { // 啥也不写,让该方法空执行 }
4.2 单例对象的retain count始终为1,因此还需要重写retain方法
- (id)retain { return self; }
- (NSUInteger)retainCount { return 1; }
- (id)autorelease { return self; }
4.3 再严谨一点,把copy也重写了.让copy时,也始终返回一个实例
+ (id) copyWithZone:(NSZone *)zone { return _instance; }
至此httpTool的单例对象就真的做完了,如果account类也要做成单例,步骤如下:
5. 但是单例使用太频繁了,如果account类也要做成单例,又要重复以上步骤
.h文件
+ (id)sharedAccount;
.m文件
static Account *_instance;
+ (id)sharedAccount{ //…… }
+ (id)allocWithZone:(NSZone *)zone { //…… }
通过上面的代码可以知道,无非就是把类名替换一下而已,所以为了快速生成单例,使用宏.
利用宏来快速生成单例
.h文件
#define single_interface(class) +(class *)shared##class
.m文件 ps: 每一行末尾加是告诉编译器 下面那行也是宏的一部分,最后一行不要加
#define single_implementation(class)
static class *_instance;
+ (id)shared##class{
if(_instance == nil){
_instance = [[self alloc] init];
}
return _instance;
}
+ (id)allocWithZone:(NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
为了便于拷贝,提供一下代码:
1 //把本段代码放在pch文件里 2 #define single_interface(class) + (class *)shared##class; 3 4 5 #define single_implementation(class) 6 static class *_instance; 7 8 + (class *)shared##class 9 { 10 if (_instance == nil) { 11 _instance = [[self alloc] init]; 12 } 13 return _instance; 14 } 15 16 + (id)allocWithZone:(NSZone *)zone 17 { 18 static dispatch_once_t onceToken; 19 dispatch_once(&onceToken, ^{ 20 _instance = [super allocWithZone:zone]; 21 }); 22 return _instance; 23 }
1 // 欲做成单例的类的.h文件,例如httpTool类 2 #import <Foundation/Foundation.h> 3 @class QKinstance; 4 @interface QKinstance : NSObject 5 single_interface(QKinstance) 6 @end
1 // 欲做成单例的类的.m文件 2 #import "QKinstance.h" 3 @implementation QKinstance 4 single_implementation(QKinstance) 5 @end