I got crash report for my mobile application
private var _timedEvents: SynchronizedBarrier<[String: TimeInterval]>
private var timedEvents: [String: TimeInterval] {
get {
_timedEvents.value
}
set {
_timedEvents.value { $0 = newValue }
}
}
func time(event: String) {
let startTime = Date.now.timeIntervalSince1970
trackingQueue.async { [weak self, startTime, event] in
guard let self else { return }
var timedEvents = self.timedEvents
timedEvents[event] = startTime
self.timedEvents = timedEvents
}
}
From the report, the crash is happening at _timedEvents.value { $0 = newValue }
struct ReadWriteLock {
private let concurentQueue: DispatchQueue
init(label: String,
qos: DispatchQoS = .utility) {
let queue = DispatchQueue(label: label,
qos: qos,
attributes: .concurrent)
self.init(queue: queue)
}
init(queue: DispatchQueue) {
self.concurentQueue = queue
}
func read<T>(closure: () -> T) -> T {
concurentQueue.sync { closure() }
}
func write<T>(closure: () throws -> T) rethrows -> T {
try concurentQueue.sync(flags: .barrier) { try closure() }
}
}
struct SynchronizedBarrier<Value> {
private let lock: ReadWriteLock
private var _value: Value
init(_ value: Value,
lock: ReadWriteLock = ReadWriteLock(queue: DispatchQueue(label: "com.example.SynchronizedBarrier",
attributes: .concurrent))) {
self.lock = lock
self._value = value
}
var value: Value { lock.read { _value } }
mutating func value<T>(execute task: (inout Value) throws -> T) rethrows -> T {
try lock.write { try task(&_value) }
}
}
What could be the reason for the crash? I have attached the crash report.
var value: Value { lock.read { _value } }
Isn't SynchronizedBarrier<Value>.value
a read-only computed property (i.e. doesn't have a setter), and thus you can't set _timedEvents.value
to a new value using _timedEvents.value { $0 = newValue }
?
I'd try changing SynchronizedBarrier<Value>.value
to this:
var value: Value {
get {
lock.read { _value }
}
set {
lock.write { _value = newValue }
}
}
I haven't tested it, so let me know if this works or not.