iOS 单例模式的写法

来源:互联网 发布:淘宝卖药品 编辑:程序博客网 时间:2024/06/06 18:30

iOS的单例模式有两种官方写法,如下:

1)不使用GCD的方式

#import "Manager.h"static Manager *manager;@implementation Manager+(Manager *)defaultManager{    if(!manager)        manager=[[self allocWithZone:NULL] init];    return  manager;}@end

2)使用GCD的方式

#import "Manager.h"@implementation Manager+(Manager *)sharedManager{  static dispatch_once_t predicate;  static Manager * sharedManager;  dispatch_once(&predicate, ^{    sharedManager=[[Manager alloc] init];  });  return sharedManager;}@end

注明:dispatch_once这个函数, 它可以保证整个应用程序生命周期中某段代码只被执行一次!
具体使用:

#import <Foundation/Foundation.h>  #import "Singleton.h"  int main(int argc, const charchar * argv[]) {      @autoreleasepool {          Singleton* obj1 = [Singleton shareInstance] ;          NSLog(@"obj1 = %@.", obj1) ;          Singleton* obj2 = [Singleton shareInstance] ;          NSLog(@"obj2 = %@.", obj2) ;          //          Singleton* obj3 = [[Singleton alloc] init] ;          NSLog(@"obj3 = %@.", obj3) ;      }      return 0;  } 

输出结果为 :

2014-12-15 16:06:28.344 ObjcSingleton[8847:303] obj1 = <Singleton: 0x1001086e0>.  2014-12-15 16:06:28.346 ObjcSingleton[8847:303] obj2 = <Singleton: 0x1001086e0>.  2014-12-15 16:06:28.346 ObjcSingleton[8847:303] obj3 = <Singleton: 0x100103940>.  

可以看到,当我们调用shareInstance方法时获取到的对象是相同的,但是当我们通过alloc和init来构造对象的时候,得到的对象却是不一样的。
那么问题就来了,我们通过不同的途径得到不同的对象,显然是不行的。我们必须要确保对象的唯一性,所以我们就需要封锁用户通过alloc和init以及copy来构造对象这条道路。
我们知道,创建对象的步骤分为申请内存(alloc)、初始化(init)这两个步骤,我们要确保对象的唯一性,因此在第一步这个阶段我们就要拦截它。当我们调用alloc方法时,oc内部会调用allocWithZone这个方法来申请内存,我们覆写这个方法,然后在这个方法中调用shareInstance方法返回单例对象,这样就可以达到我们的目的。拷贝对象也是同样的原理,覆写copyWithZone方法,然后在这个方法中调用shareInstance方法返回单例对象。看代码吧:

#import "Singleton.h"  @implementation Singleton  static Singleton* _instance = nil;  +(instancetype) shareInstance  {      static dispatch_once_t onceToken ;      dispatch_once(&onceToken, ^{          _instance = [[super allocWithZone:NULL] init] ;      }) ;      return _instance ;  }  +(id) allocWithZone:(struct _NSZone *)zone  {      return [Singleton shareInstance] ;  }  -(id) copyWithZone:(struct _NSZone *)zone  {      return [Singleton shareInstance] ;  }  @end  

再看看效果如何:

main :   #import <Foundation/Foundation.h>  #import "Singleton.h"  int main(int argc, const charchar * argv[]) {      @autoreleasepool {          Singleton* obj1 = [Singleton shareInstance] ;          NSLog(@"obj1 = %@.", obj1) ;          Singleton* obj2 = [Singleton shareInstance] ;          NSLog(@"obj2 = %@.", obj2) ;          //          Singleton* obj3 = [[Singleton alloc] init] ;          NSLog(@"obj3 = %@.", obj3) ;          Singleton* obj4 = [[Singleton alloc] init] ;          NSLog(@"obj4 = %@.", [obj4 copy]) ;      }      return 0;  }  

输出结果:

2014-12-15 16:11:24.734 ObjcSingleton[8979:303] obj1 = <Singleton: 0x100108720>.  2014-12-15 16:11:24.735 ObjcSingleton[8979:303] obj2 = <Singleton: 0x100108720>.  2014-12-15 16:11:24.736 ObjcSingleton[8979:303] obj3 = <Singleton: 0x100108720>.  2014-12-15 16:11:24.736 ObjcSingleton[8979:303] obj4 = <Singleton: 0x100108720>. 

可以看到获取到的对象都是一样的了。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 门外装监控没有预留电线怎么办 框架柱主筋柱顶预留长度不够怎么办 遇到很嚣张的人怎么办 在地板砖上铺木地板卧室门怎么办 宝宝打预防针的本子丢了怎么办 宝宝打预防针本子丢了怎么办 打疫苗的本子丢了怎么办 麦客收割机麦秸里加麦粒怎么办 高铁乘务员身高不够怎么办 坐火车买到站票怎么办 买上车补票原票怎么办? 买的商务座补票怎么办 12306账号被别人登录怎么办 飞机不提供餐食怎么办 12306退票支付宝失败怎么办 12306重复支付怎么办支付宝 支付宝登的12306账号怎么办 没买儿童高铁票怎么办 网上订的机票怎么办托运 半夜买高铁票不出票怎么办 轻轨少买了一站怎么办 高铁火车票丢了怎么办 如果高铁票丢了怎么办 高铁票丢了怎么办 报销 高铁如果没赶上怎么办 高铁管家待核验怎么办 动车没有票了怎么办 12306取消订单3次怎么办 【12306取消订单3次怎么办】 火车票取消订单3次怎么办 12306收不到验证码怎么办 安逸花验证码次数限制怎么办 航班晚点导致错过转机怎么办 想去沈阳站送站怎么办 高铁没有赶上车怎么办 火车晚点赶不上下一趟车怎么办 列车晚点影响下一趟车怎么办? 高铁晚点赶不上下班车怎么办 火车在半路坏了怎么办 做火车中途坏了怎么办 员工怀孕不上班保险怎么办