Min*_*ing 5 thread-safety swift
我通过键(对象)访问字典,大多数情况下工作正常,但有时它会崩溃:
-[__NSCFNumber objectForKey:]: 无法识别的选择器发送到实例 0x8000000000000000
我发现的最接近我的问题是这个。
这是我的(简化的)代码:
class Meal {
private static let KEY = Date()
private static let KEY_Q = DispatchQueue(label: "Meal.KEY")
static var menus = OrderedDictionary<Date, [Int:Meal]>()
static func test() throws {
var date: Date?
var menu: [Int:Meal]?
try KEY_Q.sync {
menu = Meal.menus[KEY] // <-- Error
if menu == nil {
date = KEY.clone()
}
}
DispatchQueue.main.async {
//This needs to run on the UI Thread, since it also loops over Meal.menus
if date != nil {
Meal.menus[date!] = [Int:Meal]()
}
}
}
}
class Date: Hashable & Comparable {
var days = 0
func hash(into hasher: inout Hasher) {
hasher.combine(days)
}
func clone() -> Date {
let date = Date()
date.days = days
return date
}
}
class OrderedDictionary<keyType: Hashable, valueType>: Sequence {
var values = [keyType:valueType]()
subscript(key: keyType) -> valueType? {
get {
return self.values[key]
}
}
}
Run Code Online (Sandbox Code Playgroud)
笔记:
menus。UI ThreadKEY(不是引用KEY)的克隆hash(into hasher: inout Hasher)问题:
KEY对象和UI Thread?hash(into hasher: inout Hasher)正确?这看起来非常像一个线程问题(该地址0x8000000000000000非常可疑),因此您可以按照与读取相同的方式序列化写入:
DispatchQueue.main.async {
//This needs to run on the UI Thread, since it also loops over Meal.menus
if let date = date {
KEY_Q.sync {
Meal.menus[date] = [Int:Meal]()
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了避免在其他地方无意中重新引入错误的可能性,您还可以考虑将队列和访问包装在一个小辅助对象中(这样访问只能发生在正确的队列上)。
| 归档时间: |
|
| 查看次数: |
2175 次 |
| 最近记录: |