我在
Swift 3中创建了一个简单的单例:
class MySingleton { private var myName: String private init() {} static let shared = MySingleton() func setName(_ name: String) { myName = name } func getName() -> String { return myName } }
由于我使init()私有,并且声明的共享实例是静态let,我认为初始化器是线程安全的.但是myName的getter和setter函数呢,它们是否安全?
解决方法
你写的那些获取者不是线程安全的,你是对的.在Swift中,目前实现此目的的最简单(读取最安全)方法是使用Grand Central dispatch队列作为锁定机制.最简单(也是最容易推理)的方法是使用基本的串行队列.
class MySingleton { static let shared = MySingleton() // Serial dispatch queue private let lockQueue = dispatchQueue(label: "MySingleton.lockQueue") private var _name: String var name: String { get { return lockQueue.sync { return _name } } set { lockQueue.sync { _name = newValue } } } private init() { _name = "initial name" } }
使用串行调度队列将保证先进先出执行以及实现对数据的“锁定”.也就是说,在更改数据时无法读取数据.在这种方法中,我们使用sync来执行实际的数据读写,这意味着调用者总是被迫等待轮到其他类似于其他锁定原语.
注意:这不是most performant方法,但它易于阅读和理解.它是一种很好的通用解决方案,可以避免竞争条件,但并不意味着为并行算法开发提供同步.
资料来源:
https://mikeash.com/pyblog/friday-qa-2015-02-06-locks-thread-safety-and-swift.html
What is the Swift equivalent to Objective-C’s “@synchronized”?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。