ios – 单个吸气剂和固定器的螺纹安全性

我在 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”?

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...