我目前有一个数组,它迭代了值图像路径,并希望在第一个中的for循环中异步检索这些图像。我尝试过使用两个调度组,但总是在检索图像之前返回完成处理程序。
static func getAllEntriesWithDisplayModel(completion: @escaping (_ models: [EntryDisplayModel]) -> ()) -> (){
let entries = Array(realm.objects(Entry.self)).reversed()
var displayModels: [EntryDisplayModel] = []
let options = PHFetchOptions()
let entriesGroup = DispatchGroup()
entries.forEach{
entriesGroup.enter()
var model = EntryDisplayModel(entry: $0)
let paths: [String] = $0.imagePaths.flatMap{en in
en.path
}
let assets = PHAsset.fetchAssets(withLocalIdentifiers: paths, options: options)
assets.enumerateObjects({ (object, count, stop) in
model.assets?.append(object)
})
let assetsGroup = DispatchGroup()
let requestOptions = PHImageRequestOptions()
requestOptions.resizeMode = PHImageRequestOptionsResizeMode.exact
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryMode.highQualityFormat
requestOptions.isSynchronous = true
var images: [UIImage]? = []
model.assets?.forEach{
assetsGroup.enter()
// Fetch images using local paths from images save
PHImageManager.default().requestImage(for: $0, targetSize: PHImageManagerMaximumSize, contentMode: PHImageContentMode.default, options: requestOptions, resultHandler: { (image, info) in
guard let img = image else {
assetsGroup.leave()
return
}
images?.append(img)
assetsGroup.leave()
})
}
assetsGroup.notify(queue: .main, execute: {
model.images = images
print("FETCHED \(images?.count ?? 0) IMAGES")
print("DISPLAY MODEL CREATED ")
displayModels.append(model)
})
}
entriesGroup.leave()
//Returns too early
entriesGroup.notify(queue: .main, execute: {
print(" FINISHED CREATING DISPLAY MODELS")
completion(displayModels)
})
}
答案 0 :(得分:2)
似乎您的代码调用过早entriesGroup.leave()
。您知道,您的assetsGroup.leave()
在完成处理程序中被调用,而不是在forEach
循环结束后立即调用:
static func getAllEntriesWithDisplayModel(completion: @escaping (_ models: [EntryDisplayModel]) -> ()) -> (){
//...
entries.forEach{
entriesGroup.enter()
//...
let assetsGroup = DispatchGroup()
//...
model.assets?.forEach {_ in
assetsGroup.enter()
// Fetch images using local paths from images save
PHImageManager.default().requestImage(for: $0, targetSize: PHImageManagerMaximumSize, contentMode: PHImageContentMode.default, options: requestOptions, resultHandler: { (image, info) in
//...
assetsGroup.leave()
}
}
assetsGroup.notify(queue: .main, execute: {
model.images = images
print("FETCHED \(images?.count ?? 0) IMAGES")
print("DISPLAY MODEL CREATED ")
displayModels.append(model)
entriesGroup.leave() //<-`entriesGroup.leave()` needs to be called after all processing for the entry is finished.
})
}
//entriesGroup.leave() //<-It is too early to call `entriesGroup.leave()` here
entriesGroup.notify(queue: .main, execute: {
print(" FINISHED CREATING DISPLAY MODELS")
completion(displayModels)
})
}