【问题标题】:Threading CompletionHandler Swift线程 CompletionHandler Swift
【发布时间】:2020-04-13 10:05:10
【问题描述】:

我尝试从解析服务器获取数据。因此它需要 2 个后台线程。但我没有设法以正确的方式等待完成。所以我把它分解成下面的代码:

 func load(loadCompletion: @escaping () -> ()) {
    let delegate = object as! AppDelegate
    parseQuery.findObjectsInBackground { (result: [PFObject]?, error: Error?) in
        self.getAllData(result: result, delegate: delegate, error: error) {
            loadCompletion()
        }
    }
}

func getAllData(result: [PFObject]?, delegate: AppDelegate, error: Error?, allDataCompletion: @escaping () -> ()) {
    if error == nil && result != nil {
        for obj in result! {
            let date: Date = obj["Date"] as! Date
            let coordinates: PFGeoPoint = obj["Coordinates"] as! PFGeoPoint
            let imageFile: PFFileObject = obj["Image"] as! PFFileObject
            let lat: CLLocationDegrees = coordinates.latitude
            let long: CLLocationDegrees = coordinates.longitude
            let cllCoordinates = CLLocationCoordinate2D(latitude: lat, longitude: long)
            self.getImageData(imageFile: imageFile) { (image) in
                let poo = Poo(coordinates: cllCoordinates, dateTime: date, image: image)
                delegate.poos.append(poo)
            }
        }
        allDataCompletion()
    }
}

func getImageData(imageFile: PFFileObject, imageDataCompletion: @escaping (UIImage?) -> () ) {
    var image: UIImage? = nil
    imageFile.getDataInBackground { (data, error) in
        if error == nil && data != nil {
            image = UIImage(data: data!)
        }
        imageDataCompletion(image)
    }
}

所以,我想在委托中设置数组,但不幸的是 loadCompletion() 在数组被填充之前被调用。请帮助我以正确的顺序运行它。谢谢!

【问题讨论】:

  • 因为您在从 getImageData 后台调用获取所有数据之前调用了 allDataCompletion。

标签: swift multithreading parse-platform background-process completionhandler


【解决方案1】:

一个简单的解决方案是修改您的getAllData 函数并在获取最后一个对象的图像数据后调用allDataCompletion

func getAllData(result: [PFObject]?, delegate: AppDelegate, error: Error?, allDataCompletion: @escaping () -> ()) {
    if error == nil && result != nil {
        for (idx, obj) in result!.enumerated() {
            let date: Date = obj["Date"] as! Date
            let coordinates: PFGeoPoint = obj["Coordinates"] as! PFGeoPoint
            let imageFile: PFFileObject = obj["Image"] as! PFFileObject
            let lat: CLLocationDegrees = coordinates.latitude
            let long: CLLocationDegrees = coordinates.longitude
            let cllCoordinates = CLLocationCoordinate2D(latitude: lat, longitude: long)
            self.getImageData(imageFile: imageFile) { (image) in
                let poo = Poo(coordinates: cllCoordinates, dateTime: date, image: image)
                delegate.poos.append(poo)
                if idx == result!.endIndex-1{
                    allDataCompletion()
                }
            }
        }

    }
}

或使用DispatchGroup / Synchronizing Async Code

【讨论】:

  • 谢谢,我没有考虑在最后一轮调用它的可能性......但是什么数组?它在哪里实例化?是 result.endIndex 吗?
  • 是的,这是结果!.endIndex-1...完美!非常感谢!
猜你喜欢
  • 2021-10-26
  • 2015-11-29
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多