簡體   English   中英

如何在兩個循環中使用DispatchGroup

[英]How to use DispatchGroup with two loops

我目前有一個數組,用於遍歷for值圖像路徑,並希望在第一個內的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()調用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)
    })
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM