swift设计模式:(五)单例(Singleton Pattern)

单例模式

定义:确保一个类只有一个实例,并提供一个全局访问点

简单来说就是 一个类在程序运行期间只能生成一个实例

一、使用GCD实现单例

1、swift 3.0以前

使用GCD中的dispatch_once来创建单例对象

class SingletonManager {
    static private var onceToken: dispatch_once_t = 0
    static private var staticInstance: SingletonManager? = nil
    static func sharedInstance() -> SingletonManager {
        dispatch_once(&onceToken) {
            staticInstance = SingletonManager()
        }
        return staticInstance!
    }
    private init() {}
}
测试

在swift3.0之前,可以使用 unsafeAddressOf 方式打印对象的内存地址

let singleton1 = SingletonManager.sharedInstance()
let singleton2 = SingletonManager.sharedInstance()
unsafeAddressOf(singleton1)
unsafeAddressOf(singleton2)

2、swift3.0以后

在swift3.0及以后,dispatch_once_t 及unsafeAddressOf 在swift3已经废弃。

如果仍想继续使用GCD的方法创建单例,需要对DispatchQueue进行扩展,实现dispatch_once的功能

1)对DispatchQueue进行扩展

//扩展DispatchQueue实现原有的功能
public extension DispatchQueue{
    private static var _onceTracker = [String]()
    
    public class func once(_ token : String, block:@noescape(Void)->Void){
        objc_sync_enter(self)
        defer{
            objc_sync_exit(self)
        }
        if _onceTracker.contains(token) {
            return
        }
        _onceTracker.append(token)
        block()
    }
}

2)创建单例

class SingletonManager{
    
    private static let onceToken = NSUUID().uuidString
    private static var staticInstance : SingletonManager? = nil
    static func sharedInstance()->SingletonManager{
        DispatchQueue.once(onceToken) {
            staticInstance = SingletonManager()
        }
        return staticInstance!
    }
    private init() {}
}

3)创建获取内存地址的方法

//查看对象内存地址
func printAdress(_ values : AnyObject...){
    for value in values {
        print(Unmanaged.passUnretained(value).toOpaque())
    }
}

4)测试

print("------GCD实现单例")
    let singleton1 = SingletonManager.sharedInstance()
    let singleton2 = SingletonManager.sharedInstance()
    printAdress(singleton1 as AnyObject, singleton2 as AnyObject)

3、测试结果

GCD方式创建单例,测试的两个单例对象内存地址是同一个
在这里插入图片描述

二、使用静态私有常量和静态方法来实现单例

1、单例的创建

创建单例的步骤:

1、先创建一个私有静态常量并分配值

2、在静态方法中对其进行返回

3、使用:使用者调用sharedInstance()方法时,就会将staticInstance实例进行返回

注意:需要将该类的构造方法 即 init() 声明成私有方法,防止外部通过构造器来直接生成实例

class SingletonManager1{
    
    private static let staticInstance : SingletonManager1 = SingletonManager1()
    static func sharedInstance()->SingletonManager1{
        return staticInstance
    }
    private init() {}
}

2、测试

通过声明两个单例对象,查看其内存地址是否一致,内存地址的打印同1中一致

let singleton3 = SingletonManager1.sharedInstance()
    let singleton4 = SingletonManager1.sharedInstance()
    printAdress(singleton3 as AnyObject, singleton4 as AnyObject)

单例对象的内存地址是同一个
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值