【问题标题】:iOS Swift5 will using NSMutableDictionary with locks instead of var [:] ensure thread safety?iOS Swift5 将使用带锁的 NSMutableDictionary 而不是 var [:] 确保线程安全?
【发布时间】:2019-06-17 22:19:57
【问题描述】:

我正在调试我在项目中继承的 swift 类。曾尝试使用带有信号量的 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
    }
}

或者 - 有没有办法使用诸如 mutatinginout 之类的 swift 关键字来确保信号量会阻止多个线程各自使用 swift 的副本字典?

更新:更高级别的代码中存在错误,创建了 2 个独立的 ThreadSafeDictionary 实例。修复解决了并发问题。

【问题讨论】:

  • 副本与您的问题有什么关系?该结构包含在您的类中,只要将“字典”属性分配给它,它就应该可以工作。也许你遗漏了一些关于如何使用它的非常重要的信息。

标签: ios thread-safety nsmutabledictionary swift5


【解决方案1】:

如果你将一个 Swift 目录(例如 struct,)包装到一个 Swift 类(一个引用类型)中,你会以某种方式失去 struct 的写时复制机制(这确实是为了防止多线程问题) .因此,如果您将内部的directory 成员从 Swift 类型更改为 Foundation 的 NSMutableDirectory,您将不会获得任何收益。此外,mutatinginout 并不意味着任何线程安全。

要使ThreadSafeDictionary 线程安全,您需要包装内部目录的所有访问方法,正如您在func add...() 函数中所描述的那样。除了使用信号量,您还可以将 GCD 与您自己的串行队列一起使用。

【讨论】:

  • 谢谢 - 我发现了一个不同的错误,它导致创建 2 个 ThreadSafeDictionary 实例,看起来好像调用代码复制了类的内部变量。
猜你喜欢
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
相关资源
最近更新 更多