Swift中Singleton的实现

一、意图

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

二、使用场景

1、使用场景

  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

2、实现的重要三个步骤

  • 私有化构造方法(Swift不支持)
  • 使用一个静态变量保存实例的引用 
  • 提供一个全局的访问方法

 三、 Swift语言下的实现

Swift语言不支持变量及方法的权限,没有办法隐藏变量及方法,可以随意直接创建一个实例。单例的创建有很多写法,Swift支持只有struct支持静态变量,class不支持静态变量,所以很容易想到,在类的内部使用struct就能解决引用的保存问题,代码如下:

class SwiftSingleton {
  class var shared: SwiftSingleton {
   dispatch_once(&Inner.token) {    Inner.instance = SwiftSingleton()   }   return Inner.instance!  }  struct Inner {   static var instance: SwiftSingleton?   static var token: dispatch_once_t = 0  }  }
运行如下测试代码,进行简单测试: 
class SwiftSingletonTest: XCTestCase {
  
  func testSingleton() {   let singleton1 = SwiftSingleton.shared   let singleton2 = SwiftSingleton.shared   assert(singleton1 === singleton2, "pass")  }  }
运行结果,左侧绿色对号代表执行通过: 

其中===在Swift中代表“等价于”,比较的是两个变量或者常量的引用地址,只能用于class的比较

在Swift中static类型变量会自动实现成延迟加载模式,也可以更简单的实现成如下:

class SwiftSingleton {
    class var shared: SwiftSingleton {
        return Inner.instance
    }
    
    struct Inner {
        static let instance = SwiftSingleton() } }
在所有语言中单例分为懒汉模式(延迟加载),饿汉模式,一般为了避免资源浪费,都喜欢实现成懒汉模式,即使用时在生成实例。在Swift语言中,由于static关键字做了优化,自动实现了 延迟加载模式,所以上面的代码实现的是懒汉模式而并非饿汉模式 

四、可能引起错误的实现

class与struct一个非常重要的区别:

class:传引用 
struct:传值 

有部分人可能想通过struct来直接实现单例模式,由于struct传递时是传的值,会造成内存中有多个拷贝,测试如下:

struct SwiftSingleton {
  var name: String = "1"
  static let shared = SwiftSingleton() } var single1 = SwiftSingleton.shared var single2 = SwiftSingleton.shared single2.name = "2" println("------->\(single1.name)") println("------->\(single2.name)")
打印结果如下: 
------->1
------->2
Program ended with exit code: 0
 
从上面可以看到,通过struct下的实现,我们保证有且仅有一个实例,这种实现方式是错误的

转载于:https://www.cnblogs.com/motoyang/p/4858730.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值