我做了一个简单的聊天应用。
在主线程上,我接收消息,然后在后台线程上,如果需要,我下载userDatas,如果完成了,那么我向另一个ViewController发送Notification,然后更新一个tableView。 (因此它必须在主线程上)
我在使用DispatchQueue.global().async
+ DispatchQueue.main.async
时遇到问题
这是新的代码。使用DispatchQueue.global()。sync安全吗?
socket.on("message") {
(data, socketAck) -> Void in
guard let dataArray = data[0] as? [String: Any] else {
return
}
// Loaded the message
guard let message = dataArray["message"] as? String, let userId = dataArray["userId"] as? Int
return
}
// Load user data if not loaded
let loadChatUserData_dispatchGroup = DispatchGroup()
DispatchQueue.global().async {
// Created a dispatchGroup so the whole function finished only if this is finished too
loadChatUserData_dispatchGroup.enter()
self.chatFunctions.loadChatUserDataIfNeeded(users: [userId]) {
response in
if let response = response {
if response!.type == 0 {
print(response)
return
}
}
loadChatUserData_dispatchGroup.leave()
}
}
let chatMessageData = ["chatMessage": chatMessage] as [String : Any]
DispatchQueue.global().async {
loadChatUserData_dispatchGroup.wait(timeout: .now() + 60)
DispatchQueue.global().sync {
// If loadUserDatas is finished, or 60seconds passed, let it update the tableview
NotificationCenter.default.post(name: .updateChatMessages, object: nil, userInfo: chatMessageData)
}
}
}
原始代码(导致我看到tableView错误):
.
.
// Load user data if not loaded,
let loadChatUserData_dispatchGroup = DispatchGroup()
DispatchQueue.global().async {
loadChatUserData_dispatchGroup.enter()
self.chatFunctions.loadChatUserDataIfNeeded(users: [userId]) {
response in
if let response = response {
if response!.type == 0 {
print(response)
return
}
}
loadChatUserData_dispatchGroup.leave()
}
}
let chatMessageData = ["chatMessage": chatMessage] as [String : Any]
DispatchQueue.global().async {
loadChatUserData_dispatchGroup.wait(timeout: .now() + 60)
DispatchQueue.main.async {
// PROBLEM HERE: Even though this was called on the main thread,
// it added a closure to be run in the next iteration of the main run loop, therefore it crashes..
NotificationCenter.default.post(name: .updateChatMessages, object: nil, userInfo: chatMessageData)
}
}