iOS Swift5 会用带锁的NSMutableDictionary 代替var [:] 保证线程安全吗?
iOS Swift5 will using NSMutableDictionary with locks instead of var [:] ensure thread safety?
我正在调试我在项目中继承的 swift class。尝试使用带有信号量的 swift 字典创建线程安全字典。代码在多线程环境中失败 - swift 字典被视为结构并在突变时被复制,无论信号量如何。
我试图理解:用核心基础 NSMutableDictionary(带有信号量)替换 swift 基于结构的字典是否能确保代码的线程安全?
I see this answer for Objective-C,但我的问题是关于修改swift代码。
public class ThreadSafeDictionary<KeyType: Hashable, ValueType> {
private var dictionary: [KeyType: ValueType] = [:]
//change to:
private let dictionary = NSMutableDictionary() //will this make the mutating code thread safe?
public func add(key: KeyType, value: ValueType) {
// semaphore wait
// set value in dictionary
// semaphore signal
}
}
或者 - 有没有办法使用 swift 关键字,如 mutating 或 inout 来确保信号量会防止多个线程各自使用 swift 字典的副本?
更新:更高级别的代码中存在错误,创建了 2 个独立的 ThreadSafeDictionary 实例。解决并发问题的修复。
如果将 Swift 目录(例如结构)包装到 Swift class(引用类型)中,您将以某种方式丢失 copy-on-write-mechanism结构(这确实是为了防止多线程问题)。因此,如果您将内部 directory
成员从 Swift 类型更改为 Foundation 的 NSMutableDirectory
类型,您将不会获得任何收益。此外,mutating
或 inout
并不意味着任何线程安全。
要使ThreadSafeDictionary
线程安全,您需要包装内部目录的所有访问方法,如您在func add...()
函数中描述的那样。除了使用信号量,您还可以将 GCD 与您自己的串行队列一起使用。
我正在调试我在项目中继承的 swift class。尝试使用带有信号量的 swift 字典创建线程安全字典。代码在多线程环境中失败 - swift 字典被视为结构并在突变时被复制,无论信号量如何。
我试图理解:用核心基础 NSMutableDictionary(带有信号量)替换 swift 基于结构的字典是否能确保代码的线程安全?
I see this answer for Objective-C,但我的问题是关于修改swift代码。
public class ThreadSafeDictionary<KeyType: Hashable, ValueType> {
private var dictionary: [KeyType: ValueType] = [:]
//change to:
private let dictionary = NSMutableDictionary() //will this make the mutating code thread safe?
public func add(key: KeyType, value: ValueType) {
// semaphore wait
// set value in dictionary
// semaphore signal
}
}
或者 - 有没有办法使用 swift 关键字,如 mutating 或 inout 来确保信号量会防止多个线程各自使用 swift 字典的副本?
更新:更高级别的代码中存在错误,创建了 2 个独立的 ThreadSafeDictionary 实例。解决并发问题的修复。
如果将 Swift 目录(例如结构)包装到 Swift class(引用类型)中,您将以某种方式丢失 copy-on-write-mechanism结构(这确实是为了防止多线程问题)。因此,如果您将内部 directory
成员从 Swift 类型更改为 Foundation 的 NSMutableDirectory
类型,您将不会获得任何收益。此外,mutating
或 inout
并不意味着任何线程安全。
要使ThreadSafeDictionary
线程安全,您需要包装内部目录的所有访问方法,如您在func add...()
函数中描述的那样。除了使用信号量,您还可以将 GCD 与您自己的串行队列一起使用。