美文网首页APP & program
iOS 设计模式的应用 ④ 单例模式

iOS 设计模式的应用 ④ 单例模式

作者: _涼城 | 来源:发表于2022-05-07 08:57 被阅读0次

    什么是单例(Singleton)

       在数学和逻辑学中,单例定义为”有且仅有一个元素的集合“,在无论什么情况下,获取到的都是同一个值。在程序中,单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。这个方法应该是类方法,阻止所有想要生成对象的访问,避免一个全局使用的类频繁地创建和销毁。

    单例模式的静态结构.png

        static uniqueInstanceSingleton 中的唯一实例,static sharedInstance 将它返回给客户端。通常,shareInstance 会检查 uniqueInstance 是否已经被实例化,如果没有,会生成一个实例然后返回 uniqueInstance

    什么时候使用单例

    1. 类只能有一个实例,必须从一个全局的访问点进行访问;
    2. 需要控制实例数目从而节省系统资源;

    单例的使用场景举例

    1. 文件的处理
    2. 设备管理,如定位
    3. 对共享资源的访问

    单例的优缺点

    优点

    1. 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
    2. 避免对资源的多重占用(比如写文件操作)。

    缺点

    没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

    单例的实现

    • 定义一个 Singleton

      @interface Singleton : NSObject
      
      +(instancetype) sharedSingletonInstance;
      
      @end
        
      
    • 声明单例对象的静态实例并将其初始化为nil.

      static Singleton *_instance = nil;
      
    • 在类的类工厂方法中(命名为“sharedInstance”或“sharedManager”),它会生成类的实例,但前提是静态实例是nil.

      + (Singleton *)sharedSingletonInstance{
          static dispatch_once_t onceToken;
          dispatch_once(&onceToken, ^{
              _instance = [class_createInstance([self class],0)initWithSingleton:true];
          });
      
          return _instance;
      }
      
    • 如果有人尝试直接分配和初始化您的类的实例而不是使用类工厂方法,覆盖该allocWithZone:方法以确保不分配另一个实例。相反,它只返回共享对象,同样将 copy 方法覆写,并自定义 init 方法。

      +(id)allocWithZone:(struct _NSZone *)zone{
          return [self sharedSingletonInstance];
      }
      - (id)copy{
          return [[self class] sharedSingletonInstance];
      }
      - (instancetype)initWithSingleton:(BOOL)singleton{
          self = [super init];
          if (self) {
          }
          return self;
      }
      - (instancetype)init
      {
          NSCAssert(FALSE, @"There can only be one Singleton instance."); 
          return nil;
      }
      
    • 也可以将 allocallocWithZonenewcopy 方法 声明为不可用

    @interface Singleton : NSObject
    
    + (Singleton *) sharedSingletonInstance;
    
    +(id)allocWithZone:(struct _NSZone *)zone NS_UNAVAILABLE;
    +(id)alloc NS_UNAVAILABLE;
    +(id)new NS_UNAVAILABLE;
    - (id)cooy NS_UNAVAILABLE;
    @end
    

    总结

        只要应用程序需要集中式的类来协调其服务,这个类就应该生成单一的实例,而不是多个实例。

    相关文章

      网友评论

        本文标题:iOS 设计模式的应用 ④ 单例模式

        本文链接:https://www.haomeiwen.com/subject/ckvturtx.html