У меня есть три асинхронных вызова. Один возвращает данные и два обратных изображения из S3 с использованием firebase. У меня есть один файл DispatchQueue и три группы отправки. Мне нужен способ для их выполнения синхронно, но они этого не делают! Я пробовал все, и .notify выполняется немедленно, что неправильно.Grand Central Dispatch Multiple DispatchGroups
Выход этого является:
изображения сделано
все сделано
group.notify делается
getImages() делается
То, что я хочу, чтобы понять, почему imagesdone выполняется до group.notify? Мне нужно выполнить первую группу, затем imageGroup, а затем avaGroup.
У меня есть три асинхронных вызова, а 2-й/3-й - несколько асинхронных вызовов. Как я могу дождаться их завершения, а затем выполнить последующие вызовы?
func loadFriendPhotos() {
let backgroundQueue = DispatchQueue(label: "com.app.queue",
qos: .utility,
target: nil)
let group = DispatchGroup()
let imageGroup = DispatchGroup()
let avaGroup = DispatchGroup()
typealias tempAlias = (username:String, imageURL: String, pathUrl:String)
var tempAliasArray = [tempAlias]()
var imageArray = [UIImage]()
var avaImageArray = [UIImage]()
group.enter()
let workItem = DispatchWorkItem {
databaseRef.child("friendPhotos").child(globalUsername).observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists() {
let enumerator = snapshot.children
var childrenCount = snapshot.childrenCount
while let rest = enumerator.nextObject() as? FIRDataSnapshot {
let name = rest.childSnapshot(forPath: "username").value as! String
let downloadURL = rest.childSnapshot(forPath: "downloadURL").value as! String
let uid = rest.childSnapshot(forPath: "uid").value as! String
let pathURL = rest.childSnapshot(forPath: "pathURL").value as! String
let downloadURLRef = storage.reference(forURL: downloadURL)
let newTempAlias = tempAlias(name, downloadURL, pathURL)
tempAliasArray.append(newTempAlias)
}
group.leave()
}
})
}
func getAvaImages() {
for index in tempAliasArray{
avaGroup.enter()
let avaItem = DispatchWorkItem {
let avaURLRef = storage.reference(forURL: index.1)
avaURLRef.data(withMaxSize: 2 * 1024 * 1024) { (data,error) in
if (error == nil) {
print("success!")
let picData = UIImage(data:data!)
avaImageArray.append(picData!)
} else {
print(error?.localizedDescription)
}
print("we left getAvaImages()")
avaGroup.leave()
}
}
backgroundQueue.async(execute: avaItem)
}
}
func getImages() {
for index in tempAliasArray{
imageGroup.enter()
let imageItem = DispatchWorkItem {
let downloadURLRef = storage.reference(forURL: index.1)
downloadURLRef.data(withMaxSize: 2 * 1024 * 1024) { (data,error) in
if (error == nil) {
let picData = UIImage(data:data!)
imageArray.append(picData!)
} else {
print(error?.localizedDescription)
}
print("we left getImages()")
imageGroup.leave()
}
}
backgroundQueue.async(execute: imageItem)
}
}
backgroundQueue.sync(execute: workItem)
group.notify(queue: DispatchQueue.main, execute: {
print("group.notify is done")
getImages()
})
imageGroup.notify(queue: DispatchQueue.main, execute: {
print("images done")
getAvaImages()
})
avaGroup.notify(queue: DispatchQueue.main, execute: {
print("all is done")
})
}
hi @ rob-napir, являются ли вызовы group.enter() одной и той же диспетчерской группой? – MattEm
Более широкий вопрос, если вы делаете несколько асинхронных вызовов, используете ли вы одну и ту же группу, или если бы был kickoffAsyncWithCompletion2 на том же уровне, что и kickOffAsyncWithCompletion, это была бы другая группа. – MattEm
. Пробник Im Imception - это группа1 автоматически выходит, вызывая group1.notify, который не должен произойти. Это не происходит и запускается после того, как NOT Nesting group.enter() – MattEm