我有以下快速代码允许将用户联系人映射到网络服务器,然后显示在 TableView 中:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
dispatch_group_enter(self.dispatch_group)
dispatch_group_async(self.dispatch_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
print("start 1")
self.contacts = self.findContacts()
dispatch_group_leave(self.dispatch_group)
print("End 1")
}
dispatch_group_enter(self.dispatch_group)
dispatch_group_async(self.dispatch_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
print("start 2")
// Method to match contacts with Firebase db:
self.mapContactsToPresentFriends(self.contacts, firebaseMainURL: self.firebaseMainURL, usersSyncID: "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de")
dispatch_group_leave(self.dispatch_group)
print("End 2")
}
dispatch_group_notify(self.dispatch_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
print("start 3")
// Final load of who is left of conacts (not user or friend)
for contact in self.contacts {
let phoneNumber = contact.phoneNumbers[0].value as! CNPhoneNumber
self.friends.append(Friend(userName: "", phoneNumber: phoneNumber.stringValue, status: 0, name: contact.givenName, userID: ""))
}
for friend in self.friends {
print(friend.status)
}
self.tableView!.reloadData()
})
}
但是,注意 print("Start 1")、print("Start 2") 和 print("Start 3") 语句,日志将执行显示为:
start 2
start 1
End 2
End 1
start 3
这会产生不准确的结果。我需要这些异步任务按顺序发生(如打印语句所示),否则结果将毫无意义。
如何重新安排以确保其有效?
最佳答案
如果您真的希望这些事情按顺序发生,则不需要单独的 block 。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
print("start 1")
let contacts = self.findContacts()
print("End 1")
print("start 2")
// Method to match contacts with Firebase db:
self.mapContactsToPresentFriends(contacts, firebaseMainURL: self.firebaseMainURL, usersSyncID: "fdb17f3a-7b7d-4aa5-9a0b-b9fb33c349de")
print("End 2")
print("start 3")
// Final load of who is left of conacts (not user or friend)
var friends: [Friend] = []
for contact in contacts {
let phoneNumber = contact.phoneNumbers[0].value as! CNPhoneNumber
friends.append(Friend(userName: "", phoneNumber: phoneNumber.stringValue, status: 0, name: contact.givenName, userID: ""))
}
for friend in friends {
print(friend.status)
}
dispatch_async(dispatch_get_main_queue()) {
// Any data/UI updates MUST be on the main queue
self.friends = friends
self.tableView!.reloadData()
}
}
另外一些需要注意的事情:
- 使用
dispatch_group_async
取代了对_enter()
和_leave()
的需要。你不需要两者。 (如果你真的想使用组,你还需要dispatch_group_notify
来完成工作。) - 当您分别调度每个 block 时,不需要外部调度(因为调用
_async()
很快)。 self.tableView.reloadData()
(和 UI 更新)必须发生在主线程上,因此,您的数据源(例如self.friends
) 也必须在主线程上更新。我已在上面的代码片段中对此进行了更改。
关于ios - 异步操作未按顺序完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37150319/