iOS 单例
制造单例对象的步骤,例如做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