Ios 循环期间执行的循环外代码

Ios 循环期间执行的循环外代码,ios,swift,loops,Ios,Swift,Loops,我试图检索用户在PHPicker中选择的图像集,并将它们存储在一个数组中。我正在迭代PHPicker结果数组,并在每次迭代中将加载的图像附加到一个变量。出于某种原因,在迭代完成之前会调用此迭代之后的代码。我尝试了while和for循环,删除了DispatchQueue.main.async,但似乎没有改变调用的顺序。很可能我做错了什么,但我真的不明白 var itemProviders: [NSItemProvider] = [] var iterator: IndexingIterator&l

我试图检索用户在PHPicker中选择的图像集,并将它们存储在一个数组中。我正在迭代PHPicker结果数组,并在每次迭代中将加载的图像附加到一个变量。出于某种原因,在迭代完成之前会调用此迭代之后的代码。我尝试了while和for循环,删除了DispatchQueue.main.async,但似乎没有改变调用的顺序。很可能我做错了什么,但我真的不明白

var itemProviders: [NSItemProvider] = []
var iterator: IndexingIterator<[NSItemProvider]>?
var images = [UIImage]()


func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true)
    
    itemProviders = results.map(\.itemProvider)
    iterator = itemProviders.makeIterator()
    
    while let itemProvider = iterator?.next(), itemProvider.canLoadObject(ofClass: UIImage.self) {
        print("\n Entered while")
        itemProvider.loadObject(ofClass: UIImage.self) { image, error in
            DispatchQueue.main.async {
                guard let image = image as? UIImage else { return }
                self.images.append(image)
                print("Image: \(image)")
                print("Images: \(self.images)")
            }
        }
    }
    displayAndStoreImages()
}


func displayAndStoreImages(){
    print("\n Entered displayAndStoreImages()")
    print("Images: \(images) \n")
    
    (...)
}
var itemProviders:[NSItemProvider]=[]
变量迭代器:索引迭代器?
var images=[UIImage]()
func选取器(picker:PHPickerViewController,didFinishPicking结果:[PHPickerResult]){
选择器。解除(动画:true)
itemProviders=results.map(\.itemProvider)
iterator=itemProviders.makeIterator()
而让itemProvider=iterator?.next(),itemProvider.canLoadObject(类:UIImage.self){
打印(“\n在打印时输入”)
loadObject(属于类:UIImage.self){image,中有错误
DispatchQueue.main.async{
guard let image=image as?UIImage else{return}
self.images.append(图像)
打印(“图像:\(图像)”)
打印(“图像:\(self.Images)”)
}
}
}
displayAndStoreImages()
}
func displayAndStoreImages(){
打印(“\n输入的displayAndStoreImages()”)
打印(“图像:\(图像)\n”)
(...)
}
这是在PHPicker中选择2个图像的结果。执行2次迭代,但不执行迭代块内的代码。相反,将执行以下代码,并且仅在此之后,才会调用迭代块中的代码。为什么循环期间要执行循环外的代码?短暂性脑缺血发作

输入时
进来时
输入displayAndStoreImages()
图片:[]
图片:
图片:[]
图片:
图片:[,]

对于这种异步工作,您需要类似于
DispatchGroup
的东西

编辑您的示例以使用它

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true)
    
    itemProviders = results.map(\.itemProvider)
    iterator = itemProviders.makeIterator()
    
    let dispatchGroup = DispatchGroup()
    
    while let itemProvider = iterator?.next(), itemProvider.canLoadObject(ofClass: UIImage.self) {

        dispatchGroup.enter()

        print("\n Entered while")
        itemProvider.loadObject(ofClass: UIImage.self) { image, error in
            DispatchQueue.main.async {
                guard let image = image as? UIImage else { return }
                self.images.append(image)
                print("Image: \(image)")
                print("Images: \(self.images)")

                dispatchGroup.leave()
            }
        }
    }
    dispatchGroup.notify(queue: DispatchQueue.main) {
        self.displayAndStoreImages()
    }
}


func displayAndStoreImages(){
    print("\n Entered displayAndStoreImages()")
    print("Images: \(images) \n")
    
}

因为您在下载图像时进行异步调用,所以在下载文件和关闭之前会调用displayAndStoreImages()executed@JoakimDanielson我在没有DispatchQueue.main.async的情况下得到了相同的结果,我在发布之前尝试过。
itemProvider.loadObject
是一个异步函数。。。因此,这就是为什么您在使用/不使用
DispatchQueue.main.async
@NewDev的情况下获得它的原因谢谢您的进一步澄清,我现在就知道了@NewDev同步调用的备选方案是什么?我一直在尝试几种替代方案,但似乎都不管用。我只想检索原始大小的所选图像。很抱歉回复太晚!感谢您的回答,了解dispatchGroup非常有用。该解决方案可行,但由于某种原因,在关闭选择器和显示图像之间需要几秒钟的时间。延迟与建议的解决方案无关,我的错。
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
    picker.dismiss(animated: true)
    
    itemProviders = results.map(\.itemProvider)
    iterator = itemProviders.makeIterator()
    
    let dispatchGroup = DispatchGroup()
    
    while let itemProvider = iterator?.next(), itemProvider.canLoadObject(ofClass: UIImage.self) {

        dispatchGroup.enter()

        print("\n Entered while")
        itemProvider.loadObject(ofClass: UIImage.self) { image, error in
            DispatchQueue.main.async {
                guard let image = image as? UIImage else { return }
                self.images.append(image)
                print("Image: \(image)")
                print("Images: \(self.images)")

                dispatchGroup.leave()
            }
        }
    }
    dispatchGroup.notify(queue: DispatchQueue.main) {
        self.displayAndStoreImages()
    }
}


func displayAndStoreImages(){
    print("\n Entered displayAndStoreImages()")
    print("Images: \(images) \n")
    
}