You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPickerViewController未遵循图片选择顺序问题求助

问题

我们的代码最低适配iOS 15,通过以下方式实现图片多选:

func chooseImage() {
    var configuration = PHPickerConfiguration()
    
    configuration.selectionLimit = 0
    
    // 配置为有序选择
    configuration.selection = .ordered
    
    configuration.filter = .images
    let picker = PHPickerViewController(configuration: configuration)
    picker.delegate = self
    present(picker, animated: true)
}

但发现按0.png、1.png、2.png、3.png、4.png的顺序选择图片时,PHPickerViewControllerDelegate中返回的结果顺序随机(例如3.png、2.png、4.png、0.png、1.png)。以下是我们的代理实现代码,无论是否使用DispatchQueue,结果顺序均随机:

class NewNoteViewController: UIViewController {
    static let theDispatchQueue = DispatchQueue(
        label: "com.xxx.yyy.theDispatchQueue",
        qos: .userInitiated,
        target: nil
    )
}

extension NewNoteViewController: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        guard !results.isEmpty else { return }
        
        print(">>>>> start the for loop")
        
        for result in results {
            result.itemProvider.loadFileRepresentation(forTypeIdentifier: UTType.image.identifier) { [weak self] (url, error) in
                
                NewNoteViewController.theDispatchQueue.sync {
                    self?.process(url)
                }
            }
        }
    }
    
    private func process(_ url: URL?) {
        precondition(!Thread.isMainThread)
        
        guard let url = url else { return }
        
        print(">>>>> url \(url)")
        
        ...
    }
}

请问出现这种随机顺序的原因是什么?

原因分析
  • results数组本身的顺序完全符合你选择图片的顺序,问题根源在于loadFileRepresentation(forTypeIdentifier:completionHandler:)方法。它是异步执行的文件加载方法,每个PHPickerResult对应的图片加载耗时受图片大小、存储位置(比如是否为iCloud云端图片、本地缓存状态)等因素影响,不同结果的加载完成时间不一致,导致回调触发的顺序是随机的。
  • 你使用的theDispatchQueue.sync仅能保证process方法在同一个串行队列中执行,避免多线程冲突,但无法改变回调本身被触发的先后顺序。比如选择顺序中的第一张图片加载耗时较长,而后面的图片加载更快,那么后面图片的回调会先被触发,先进入串行队列执行process,最终打印出来的URL顺序就会和选择顺序不符。

内容的提问来源于stack exchange,提问作者Cheok Yan Cheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:41:35