单例设计模式:在它的核心结构中只包含一个被称为单例类的特殊类。例如文件管理中的NSUserDefault,应用程序中的UIApplication,整个应用程序就这一个单例类,负责应用程序的一些操作,单例在那个文件下都能取得到。
通过单例设计模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节省系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的选择。
下面来点实在的,创建单例代码上
方法1:基于线程安全创建一个单例
.h做一下声明
+ (id)sharedInstanceBySynchronized;
.m实现一下单例类
+ (id)sharedInstanceBySynchronized
{
static Instance *instance;
//保证创建的单例线程安全
@synchronized(self){
if (instance==nil) {
instance=[[self alloc] init ];
}
{
static Instance *instance;
//保证创建的单例线程安全
@synchronized(self){
if (instance==nil) {
instance=[[self alloc] init ];
}
}
return instance;
}
这样就可以需要用到单例类的时候调用单例类的接口API,要先导入头文件才能使用
方法2:用GCD是对线程的高度封装,线程以后进一步详解
.h
+ (id)sharedInstanceByGCD;
.m
//利用GCD手写单例
+ (id)sharedInstanceByGCD
{
static Instance *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance=[[self alloc ] init ];
});
return instance;
}
+ (id)sharedInstanceByGCD
{
static Instance *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance=[[self alloc ] init ];
});
return instance;
}
测试一下是不是正确产生了一个单例,就需要我们自己用代码测试,通过打印输出两个变量的地址,就知道是不是同一个单例类
Instance *instance1=[Instance sharedInstanceByGCD];
Instance *instance2=[Instance sharedInstanceByGCD];
Instance *instance2=[Instance sharedInstanceByGCD];
NSLog(@"%@---%@",instance1,instance2);
打印输出instance1=instance2的地址,说明通过线程锁创建成功了单例
Instance *instance3=[Instance sharedInstanceBySynchronized];
Instance *instance3=[Instance sharedInstanceBySynchronized];
Instance *instance4=[Instance sharedInstanceBySynchronized];
NSLog(@"%@---%@",instance3,instance4);
打印输出instance3=instance4的地址,说明通过GCD创建成功了单例
2015-11-01 22:38:04.700 单例测试性能[746:28450] 11<Instance: 0x7f99c35170c0>---<Instance: 0x7f99c35170c0>
2015-11-01 22:38:04.700 单例测试性能[746:28450] 11<Instance: 0x7f99c3630d30>---<Instance: 0x7f99c3630d30>
2015-11-01 22:38:04.700 单例测试性能[746:28450] 11<Instance: 0x7f99c3630d30>---<Instance: 0x7f99c3630d30>
两个单例的地址相同,创建单例成功
这里我们做一下拓展,测试一下两个单例的性能
代码如下:需要用到单例需导入单例的头文件
可以在本文件调用[self test1],[self test2],看一下时间差,就能知道性能的好坏
- (void)test1
{
long num=1000;
CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
for (int i=0; i<num; i++) {
Instance *inst=[Instance sharedInstanceByGCD];
}
CFAbsoluteTime end=CFAbsoluteTimeGetCurrent();
NSLog(@"test1:%f",end-start);
{
long num=1000;
CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
for (int i=0; i<num; i++) {
Instance *inst=[Instance sharedInstanceByGCD];
}
CFAbsoluteTime end=CFAbsoluteTimeGetCurrent();
NSLog(@"test1:%f",end-start);
}
- (void)test2
{
long num=1000;
CFAbsoluteTime start=CFAbsoluteTimeGetCurrent();
for (int i=0; i<num; i++) {
Instance *ins=[Instance sharedInstanceBySynchronized];
}
CFAbsoluteTime end=CFAbsoluteTimeGetCurrent();
NSLog(@"test2:%f",end-start);
}
2015-11-01 22:38:05.880 单例测试性能[746:28450] test1:0.000168
2015-11-01 22:38:05.880 单例测试性能[746:28450] test2:0.000319
2015-11-01 22:38:08.128 单例测试性能[746:28450] test1:0.000164
2015-11-01 22:38:08.128 单例测试性能[746:28450] test2:0.000327
2015-11-01 22:38:05.880 单例测试性能[746:28450] test2:0.000319
2015-11-01 22:38:08.128 单例测试性能[746:28450] test1:0.000164
2015-11-01 22:38:08.128 单例测试性能[746:28450] test2:0.000327
从打印出来的数字可以看出GCD的单例优于Synchronized的性能