我们有一个事件跟踪模块,可以在触发报告条件时批量报告收集的事件。收集的每个事件都标有唯一的event index
。为了确保唯一性,event index
代的工作放在同步队列中,该模块将从其他线程调用。
class EventIndexManager {
fileprivate static let sharedInstance = EventIndexManager()
fileprivate var eventIndexQueue = DispatchQueue(label: "com.johnkui.EventIndex.SyncQueue")
fileprivate var curEventIndex: UInt64 = 0
static func sharedManager() -> EventIndexManager {
return sharedInstance
}
func getEventIndex() -> UInt64 {
eventIndexQueue.sync {
if self.curEventIndex != 0 {
self.curEventIndex += 1
} else {
if let prevEventIndex = UserDefaults.standard.value(forKey: "event_index") as? UInt64 {
self.curEventIndex = prevEventIndex + 1
} else {
self.curEventIndex = 1
}
}
let curEventIndex = self.curEventIndex
eventIndexQueue.async {
let eventIndex = self.curEventIndex > curEventIndex ? self.curEventIndex : curEventIndex
UserDefaults.standard.set(eventIndex, forKey: "event_index")
UserDefaults.standard.synchronize()
}
}
return self.curEventIndex
}
}
class EventTask: Taskable {
var event: String
var parameters: [String : Any]
var eventIndex: UInt64
init(event: String, parameters: [String : Any]) {
self.event = event
self.parameters = parameters
self.eventIndex = EventIndexManager.sharedManager().getEventIndex()
super.init()
}
}
DispatchQueue.main.async(execute: { () -> Void in
let task = EventTask(event: event, parameters: i18nParameters)
self.tasks.append(task)
})
这是调用堆栈的一部分
为什么会造成死锁?我的代码段有什么问题?
答案 0 :(得分:1)
您的代码中存在循环依赖:
EventIndexManager
。EventIndexManager
的init函数需要初始化的共享实例。这不起作用,因为变量sharedManager
的初始化时间不早于init函数之后。你不应该在init函数中访问sharedManager
或sharedMananger()
。