zoukankan      html  css  js  c++  java
  • OC编程之道-创建对象之单例模式

    一 何为单例singleton模式?(what)

    保证一个类只有一个实例,并提供一个访问它的全局访问点。

    二 何时使用单例模式?(where)

    1类只能有一个实例,而且必须从一个为人熟知的访问点对其访问,比如工厂方法。

    2这个唯一实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。

    为什么不用静态全局变量或是类方法呢?

    如果一个程序中两个人分别在两个地方定义了相同类型的静态变量。那么一个程序中就会有两个相同的全局对象类型。

    类方法提供了共享服务,不用创建其对象就可以访问,资源的唯一实例可以在类方法中进行维护。但是如果累需要被子类化以提供更好的服务,这一方式就不灵活。

    三 实现单例模式 (how)

    static Singleton *sharedSingleton_=nil;

    +(Singleton *)sharedInstance

    {

      if(sharedSingleton_==nil){
        sharedSingleton = [[Singleton alloc]init];

      }

      return sharedSingleton_;

    }

    需克服问题:

    发起调用的对象不能以其他方式实例化单例对象。否则就可能创建单例类的多个实例。

    对单例对象实例化的限制应该与引用计数内存模型共存。

    解决:

    static Singleton *sharedSingleton_=nil;

    +(Singleton *)sharedInstance

    {

      if(sharedSingleton_==nil){
        sharedSingleton = [[super allocWithZone:NULL]init];

      }

      return sharedSingleton_;

    }

    用super的原因是,已经在self中重载了基本对象分配方法,需要借用父类来帮助处理底层内存分配的复杂任务

    +(id)allocWithZone:(NSZone *)zone

    {

      return [[self sharedInstance] retain];//为什么retain,是有了把Singleton类变得不太严格的一种选择(即允许分配与初始化额外的实例,但shareInstance工厂方法总是返回同一个实例,否则singleton对象可能被破坏)子类可以再次重载retain、release和autorelease方法,实现合适的内存管理。

    }

    - (id)copyWithZone:(NSZone *)zone

    {

      return self;

    }

    - (NSUInteger)retain

    {

      return self;

    }

    - (NSUInteger)retainCount

    {

      return NSUIntegerMax;//4294967295

    }

    - (void)release

    {  

    //生么也不做

    }

    - (id)autorelease

    {

      return self;

    }

    alloc使用设为NULL的zone来调用allocWithZone:在默认区域为新实例分配内存。

    四 子类化单例

    如果用以上的方法,不做修改的子类化Singleton时,返回的实例总是Singleton,因为Singleton重载了所有实例化相关的方法。

    解决方法:

    +(Singleton *)sharedInstance

    {

      if(sharedSingleton_==nil){
        sharedSingleton = [NSAllocateObject([self class],0,NULL) init];

      }

      return sharedSingleton_;

    }

    第一个参数是类型,第二个参数是用于索引实例变量的额外字节数总是0,第三个参数用于指定内存中分配的区域一般为NULL表示默认区域。可以通过指定类的类型,用这个函数实例化任何对象。

    五 还要注意单例对象的线程安全

    @synchoronized()或NSLock或是dispatch_once

  • 相关阅读:
    Spring学习(一)初识Spring
    搜索引擎学习(七)解析查询
    搜索引擎学习(六)Query的子类查询
    Oracle学习(十四)分表分区
    Oracle学习(十三)优化专题
    Python学习————流程控制之while循环
    Python学习————深浅copy
    Python学习————while循环作业
    Python学习————运算符
    Python学习————与用户交互
  • 原文地址:https://www.cnblogs.com/encoreMiao/p/5200230.html
Copyright © 2011-2022 走看看