使用Concurrent Dispatch Group进行线程安全读/写阵列访问[重复]

问题描述 投票:0回答:1

这个问题在这里已有答案:

我正在开发一个照片编辑应用程序。我正在为我的用户提供将多个资源导入编辑View Controller的选项。我正在为所有“PHAsset-> Asset fetching”调用创建一个Dispatch Group。 每次调用PHAsset获取请求完成块时,我需要将获取的资产append放入Mutable Array,并按导入资产的数量更新UI(1/3导入| 2/3导入等)。 因为Swift Mutable Arrays不是线程安全的,有时我会崩溃。我想完成处理程序从多个线程调用,导致某种死锁。

使用Concurrent Dispatch Group处理线程安全读/写阵列访问的正确方法是什么?

var assets = [Asset]()

func getAssetsFromPHAssets() {

    let dispatchGroup: DispatchGroup = DispatchGroup()

    for phAsset in phAssets {

        dispatchGroup.enter() // Enter group for each asset

        PHImageManager.default().requestPlayerItem(forVideo: phAsset, options: nil, resultHandler: { (item, info) in

            let asset = Asset(playerItem: item, position: 0)
            self.assets.append(asset)

            DispatchQueue.main.async {
                self.lblImport.text = "Importing \(self.assets.count)/3"
            }

            dispatchGroup.leave() // Leave group
        })
    }

    dispatchGroup.notify(queue: DispatchQueue.main, execute: {
            print("finished importing")
        })
}
ios swift multithreading thread-safety grand-central-dispatch
1个回答
-1
投票

我建议在主线程中添加新资产:

let asset = Asset(playerItem: item, position: 0)

DispatchQueue.main.async {
    self.assets.append(asset)
    self.lblImport.text = "Importing \(self.assets.count)/3"
}

也许 - 但这取决于你在notify关闭中做了什么 - 你还应该将dispatchGroup.leave()调用移动到主队列中。

© www.soinside.com 2019 - 2024. All rights reserved.