I access a dictionary by key (object), which works fine most of the time, but sometimes it just crashes with:
-[__NSCFNumber objectForKey:]: unrecognized selector sent to instance 0x8000000000000000
The closest question to mine I found was this one.
Here is my (simplified) code:
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]
}
}
}
Note:
- Entries are added to
menus
from theUI Thread
, while my code is running in a different thread. - The keys stored in the dictionary are clones of
KEY
(not references toKEY
) - I think the error might have started occuring with the migration to Swift 5 and therefore
hash(into hasher: inout Hasher)
Questions:
- Is a Swift dictionary thread safe for insertion and access?
- How would I lock the
KEY
object and theUI Thread
? - Is
hash(into hasher: inout Hasher)
implemented correctly? - Why does this error occur and how can i fix it?