单例的目的:永远只分配一个内存给创建对象
第一种写法
.h
//1.创建代理对象
+(ContactHelper *)shareContactHelper;
.m
static ContactHelper *helper =nil;
//创建单例的方法
+(ContactHelper *)shareContactHelper{
//安全机制 保护在多线程中访问的安全
@synchronized (self){
if (helper ==nil) {
helper =[[ContactHelper alloc]init];
//单例对象不能释放 为了保证任何对象都被访问 由于他的生命周期和程序一样 所有他的空间在程序的整个运行过程中都不会被收回(因为存放在静态区啊)
[helper readDataFromPlist];
}
}return helper;
}
第二种方法:与线程结合
①ARC
.m
//定义一份变量(整个运行过程中,只有一份)
static id _instace = nil;
+(instancetype)shareAudioTool{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[super alloc]init];
});
return _instace;
}
//重写 alloc 方法 :目的控制内存分配 永远只分配一次内存
+(id)allocWithZone:(struct _NSZone *)zone
{
//里面代码永远执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
// 返回对象
return _instace;
}
//初始化就一次
-(id)init
{
if (self =[super init]) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//加载做需要的音频资源
});
}return self;
}
//这个方法是 让所有的 alloc init 都只执行一次 用于 ARC 状态下
② MRC
考虑到 release 的问题
.m
static id _instance; \
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (oneway void)release \
{ \
\
} \
\
- (id)autorelease \
{ \
return _instance; \
} \
\
- (id)retain \
{ \
return _instance; \
} \
\
- (NSUInteger)retainCount \
{ \
return 1; \
} \
\
+ (id)copyWithZone:(struct _NSZone *)zone \
{ \
return _instance; \
}
代码因为这些太长 不方便我们使用 就写成宏 可是宏只认同一行所以在每一行后面加\ 告诉系统 后面的也是他的
注:最后一行就不用了 因为你后面没有了
下面 是完整的非 ARC 的单例宏
// ## : 连接字符串和参数
#define singleton_h(name) + (instancetype)shared##name;
#define singleton_m(name) \
static id _instance; \
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
- (oneway void)release \
{ \
\
} \
\
- (id)autorelease \
{ \
return _instance; \
} \
\
- (id)retain \
{ \
return _instance; \
} \
\
- (NSUInteger)retainCount \
{ \
return 1; \
} \
\
+ (id)copyWithZone:(struct _NSZone *)zone \
{ \
return _instance; \
}
在你的工具类里只要 引入这个头文件
写两行代码就可以完成单例
.h
#import <Foundation/Foundation.h>
#import "Singleton.h"
@interface HMNetTool : NSObject
singleton_h(NetTool)
@end
.m
#import "HMNetTool.h"
@implementation HMNetTool
- (id)init
{
if (self = [super init]) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 加载资源
});
}
return self;
}
singleton_m(NetTool)
@end
总:两种方法都可以使用