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

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...