继续创造,加速成长!这是我参与「日新方案 6 月更文应战」的第5天,点击查看活动详情

  • 本文首要介绍iOS规划形式中单例形式的介绍,单例形式是咱们平时运用比较多的一种规划形式,供给了对类的目标所供给的资源的大局的拜访点,因而咱们能够运用单例回来的目标进行传递值等。

1. 什么是单例形式

单例形式是规划形式的最简单的形式了。这一形式的目的是使得类的一个目标成为体系中的仅有实例。咱们一般会运用类办法回来实例目标,因而咱们能够运用工厂办法进行实现改类在程序中只实例化一次。该办法咱们首先判读是否存在实例,不存在的话进行实例之后回来该实例。
在数学中。singleton指“单元素调集”,指仅由一个元素组合成的调集。

单例形式:确保一个类仅有一个实例,并供给一个拜访它的大局拜访点。

2. 什么时候运用单例形式

  • 只能有一个实例,并且必须从一个为人熟知的拜访点对其进行拜访,比方工厂办法。
  • 这个仅有的实例只能经过子类化进行拓宽,并且拓宽的目标不会损坏客户端代码。
    单例形式供给了一个为人熟知的拜访点,供给客户类为共享资源生成仅有实例,并经过它对共享资源进行拜访,虽然静态的大局目标引证或类办法也能够供给大局拜访点,可是大局目标无法避免类被实例化一次以上,并且类办法也短少消除耦合的灵活性
    比方咱们APP中保存用户的信息类,UserModel的信息在大局中多次被用到,同时咱们只需一次实例化,这个时候运用单例形式就能够供给了灵活性。或者是网络恳求的东西类咱们实例化一次,大局都能够运用。

3. 在Cocoa Touch中运用单例形式

咱们在开发中会发现很多的单列类,这里简单的介绍下UIApplicationNSFileManager

3.1 UIApplication

每个iOS应用程序都恰好有一个UIApplication实例(或很少是UIApplication的子类)。当应用程序发动时,体系调用UIApplicationMain(_:_:_:_:)函数。除其他使命外,此函数创立一个单例UIApplication目标,您能够运用shared拜访。
UIApplication目标为应用程序处理许多内务办理使命,包含传入的用户事情的最初路由,以及为UIController分发动作消息给适宜的目标。并且还保护应用程序中打开所有UIWindow目标的列表。应用程序目标总是被分配给一个UIApplicationDelegate目标,把运行时事情告诉给她。

3.2 NSFileManager

文件办理器目标允许您查看文件体系的内容并对其进行更改。NSFile类供给了对共享文件办理器目标的便捷拜访,该目标适用于大多数类型的文件相关操作。文件办理器目标一般是您与文件体系交互的首要形式。您运用它来定位、创立、仿制和移动文件和目录。您还能够运用它来获取有关文件或目录的信息或更改其某些特点。
能够经过defaultManager进行拜访,可是可能会存在线程安全问题。
能够从多个线程安全地调用共享NSFile目标的办法。可是,如果您运用托付接收有关移动、仿制、删除和链接操作状况的告诉,您应该创立文件办理器目标的仅有实例,将托付分配给该目标,并运用该文件办理器发动操作。

4. 代码展现

单利一般有2种写法,第一种:

static Network *_network;
+(instancetype)share
{
  if (!_network) {
    _network = [[Network alloc]init];
  }
  return _network;
}

这样写会在多线程情况下导致重复创立,不安全。一般会添加一个同步锁

+(instancetype)share
{
  @synchronized (self) {
    if (!_network) {
      _network = [[Network alloc]init];
    }
  }
  return _network;
}

继续优化下,避免每次读取造成卡顿,外面在加一层判断。

+(instancetype)share
{
   if (!_network) {
    @synchronized (self) {
      if (!_network) {
        _network = [[Network alloc]init];
      }
    }
  }
  return _network;
}

第二种:看下GCD单例写法

static Network *_network;
+(instancetype)shareInstance
{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    _network = [[Network alloc]init];
  });
  return _network;
}

当然为了避免alloccopy导致实例化咱们一般也会实现allocWithzonecopyWithZone,用来确定仅有性。

5. 总结

单例形式在我开发生涯中,运用的比较多,可是很多的单例形式运用会造成内存长期处于无法释放的状况,虽然处理了咱们传值状况保存等方便性。可是它违返了单一职责原则。单例形式可能掩盖不良规划,比方程序各组件之间相互了解过多等。