gpt4 book ai didi

swift - 如何在两个循环中使用 DispatchGroup

转载 作者:搜寻专家 更新时间:2023-11-01 07:09:02 24 4
gpt4 key购买 nike

我目前有一个数组,它遍历图像路径的值,并希望在第一个 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)
})
}

最佳答案

似乎您的代码过早调用了 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)
})
}

关于swift - 如何在两个循环中使用 DispatchGroup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46017032/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com