浅谈单例模式

       最近用到单例模式,可是之前仅限于理论阶段,现在要用到实际当中,难免会遇到困难。我查阅了一些资料,先粗略的谈一下。

       首先说一下单例模式适用的情景吧,什么时候用单例模式比较好?

当你只想让一个类只有一个实例变量,即整个程序共享这唯一的变量时,用单例比较好。它里面包含全局的一些信息,可以为全局所用

       然后说一下单例模式的构建(ARC,非ARC要多几个方法):

       首先在单例类比如就把这个单例类叫“Singleton”的.h文件中声明一个创建单例的方法,比如:+ (id)shareInstance;

       然后在.m中,

第一步: static  Singleton *shareInstance = nil;

第二步:实现.h中声明的创建单例的方法:(懒汉模式

     + (id) shareInstance 

      {

      @synchronized (self) {

      if( ! shareInstance ){

             [ [self alloc] init ]; 

             }

        }

         return sharInstance;

     }

       这样就创建了一个简单的单例模式,实际上有一部分程序员也是这样实现的,但实际上这是一个不“严格”版本,在实际中使用,可能会遇到发起调用的对象不能以其他分配方式实例化单例对象(比如 alloc),否则,就会创建多个实例。这样在要求只有一个实例对象的场合中就会遇到无法感知的bug。

       所以在.m文件中还需要加入以下方法:

       第三步:补充实现 allocWithZone  copyWithZone  retain  release  autorelease等方法

       +(id) allocWithZone:(NSZone *)zone  ( 因为这是创建实例的方法,所以是类方法)

       {

        @synchronized (self) {

            if( ! shareInstance ){

                    [ [self alloc] init ]; 

                }

             }

             return sharInstance;

      }

  - (id)copyWithZone: (NSZone *) zone{

          return self;  //保证只有一个实例变量

    }

/*

非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)

实现内存管理方法:

 -(id)retain {return self; }

- (NSUInteger) retainCount {return 1; }

- (oneway void) release { }

 - (id)autorelease {return self;}


 -(id)retain{

    return self;

    }

- (NSUInteger) retainCount  {

    return NSUIntegerMax; //执行retainCount方法时返回的一个数值,这里返回一个最大值

   }

- (oneway void) release {

   [super release];

  }

- (id) autorelease{

  return self

  }

*/

这样Singleton类就变得“严格”了。

解释:

1. static Singleton *shareInstance = nil;  

    静态全局变量,始终指向实例化出的对象。

2. +(id)shareInstance;

    外界初始化得到单例类对象的接口。这个类方法返回的就是ShareInstance,即类的一个对象。如果shareInstance为空,则实例化一个对象。如果不为空,则直接返回。这样保证了实例的唯一。

3.@synchronized (self) 

   线程锁。保证同一时间没有其他线程对self进行修改,保证线程安全性

4. + (id)allocWithZone

执行alloc方法时,会先调用allocWithZone方法创建对象

5. - (id)copyWithZone: (NSZone *) zone;

执行copy方法时会先执行此方法。  此方法防止外界拷贝造成多个实例,保证实例的唯一性。


/*

6. - ( id )retain;

  因为只有一个实例对象,所以retain不能增加引用计数

7. - (NSUInteger)retainCount

  因为只有一个实例对象,设置默认引用计数。这里是取得NSUInteger的最大值,当然也可以设置成1或者其他值。

8. - (oneway void)release;

oneway void 是用于多线程编程中,表示单项执行,不能“回滚”,即原子操作

*/


另外关于创建唯一单例的方法,自从GCD出现后,又有了新的方法,即:

+ (id)shareInstance{

    static Singleton *shareInstance;

   static dispatch_once_t onceToken;

   dispatch_once(&onceToken, ^{

        shareInstance=[ [ self alloc ]init];

    });

   return shareInstance;

}


实现机制:

       1.当调用alloc方法时,alloc方法内部会调用allocWithZone:这个方法

       2.提供一个share方法,如上实例;


优缺点:

       从线程安全性上讲,不加同步的懒汉式是线程不安全的,比如,有两个线程,一个是线程A,一个是线程B,它们同时调用alloc方法,那就可能导致并发问题。如上实例,可以加锁防止多线程同步的时候大家都创建对象。

       懒汉式是典型的时间换空间,也就是每次获取实例都会进行判断,看是否需要创建实例,浪费判断的时间。当然,如果一直没有人使用的话,骄傲就不回创建实例,则节约内存空间。


饿汉模式

       上面的是比较常用的懒汉模式,即当单例对象的获取方法第一次被调用时创建单例对象。下面说下饿汉模式,即类被加载时就创建单例对象。

       在.m文件中做以下处理:

static  Singleton *shareInstance = nil;

+ (void)Load{

  shareInstance = [[self alloc] init];

}

+ (id)allocWithZone:(NSZone *)zone{

   if (!shareInstance) {

         shareInstance = [super allocWithZone:zone];

     }

   return shareInstance;

}


+ (instancetype)shareInstance{

    return shareInstance;

}

实现机制:

当类加载到OC运行时环境中(内存),就会调用+ (void)load一次(一个类只会加载1次)

优缺点:

       饿汉式是线程安全的,因为虚拟机保证只会装载一次,在装载类的时候是不会发生并发的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值