• 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

  • 相关阅读:
    HDU
    HDU
    HDU
    2016蓝桥杯省赛C/C++A组第二题 跳蚱蜢
    2016蓝桥杯决赛C/C++A组第四题 路径之谜
    【洛谷P2397】yyy loves Maths VI (mode)【模拟】
    【洛谷P2397】yyy loves Maths VI (mode)【模拟】
    【NOIP2018】【洛谷P5017】摆渡车【DP】
    【NOIP2018】【洛谷P5017】摆渡车【DP】
    2018NOIP普及组 划水记
  • 原文地址:https://www.cnblogs.com/encoreMiao/p/5200230.html
Copyright © 2020-2023  润新知