如何在Swift中返回之前等待关闭完成

如何在Swift中返回之前等待关闭完成,swift,asynchronous,closures,Swift,Asynchronous,Closures,我有这个功能 func getSnapshot(lat: Double, lon: Double) -> UIImage? { let location = CLLocationCoordinate2DMake(37.332077, -37.332077) let region = MKCoordinateRegion(center: location, latitudinalMeters: 1000, longitudinalMeters: 1000)

我有这个功能

func getSnapshot(lat: Double, lon: Double) -> UIImage? {
        let location = CLLocationCoordinate2DMake(37.332077, -37.332077)
        let region = MKCoordinateRegion(center: location, latitudinalMeters: 1000, longitudinalMeters: 1000)
        mapSnapshotOptions.region = region
        print("a")
        mapSnapshotOptions.scale = UIScreen.main.scale
        mapSnapshotOptions.size = CGSize(width: 300, height: 300)
        mapSnapshotOptions.showsBuildings = true
        mapSnapshotOptions.showsPointsOfInterest = true

        snapShotter = MKMapSnapshotter(options: mapSnapshotOptions)
        print("b")
        var newImage: UIImage?
        self.snapShotter.start { (snapshot, error) -> Void in
            print("c")
            if error == nil {
                let image = snapshot!.image.withRenderingMode(.alwaysOriginal)
                var imageview = UIImageView(frame: CGRect(x: 30, y: 30, width: 300, height: 300))
                var label = UILabel()
                label.frame = CGRect(x: 0, y: 1, width: 30, height: 30)
                label.textAlignment = .center
                label.font = UIFont.boldSystemFont(ofSize: 12)
                label.textColor = UIColor.gray
                label.text = "my-text"
                imageview.addSubview(label)
                imageview.image = image
                newImage = image
            } else {
                print("error")
            }

        }
        print("d")
        print(newImage)
        return newImage
    }
这将返回我在
snapShotter.start
closure中设置的UIImage。我写了一些print语句来检查发生了什么,它打印出
abd nil c
,我要找的是打印
abcd(图像)

我曾尝试将闭包放入
DispatchQueue.main.async
中,但我一直得到相同的结果


有什么想法吗?

使用闭包块将图像传递回使用它的位置,而不是返回图像,如下所示:

func getSnapshot(lat: Double, lon: Double, completion: @escaping (UIImage?) -> Void) {
    let location = CLLocationCoordinate2DMake(37.332077, -37.332077)
    let region = MKCoordinateRegion(center: location, latitudinalMeters: 1000, longitudinalMeters: 1000)
    mapSnapshotOptions.region = region
    print("a")
    mapSnapshotOptions.scale = UIScreen.main.scale
    mapSnapshotOptions.size = CGSize(width: 300, height: 300)
    mapSnapshotOptions.showsBuildings = true
    mapSnapshotOptions.showsPointsOfInterest = true

    snapShotter = MKMapSnapshotter(options: mapSnapshotOptions)
    print("b")
    var newImage: UIImage?
    self.snapShotter.start { (snapshot, error) -> Void in
        print("c")
        if error == nil {
            let image = snapshot!.image.withRenderingMode(.alwaysOriginal)
            var imageview = UIImageView(frame: CGRect(x: 30, y: 30, width: 300, height: 300))
            var label = UILabel()
            label.frame = CGRect(x: 0, y: 1, width: 30, height: 30)
            label.textAlignment = .center
            label.font = UIFont.boldSystemFont(ofSize: 12)
            label.textColor = UIColor.gray
            label.text = "my-text"
            imageview.addSubview(label)
            imageview.image = image
            newImage = image
            print(newImage)
            completion(newImage)
        } else {
            print("error")
            completion(nil)
        }

    }
    print("d")
}
getSnapshot(lat: 0, lon: 0) { image in
    DispatchQueue.main.async {
        self.imageView.image = image
    }
}
使用地点将其修改为如下所示:

func getSnapshot(lat: Double, lon: Double, completion: @escaping (UIImage?) -> Void) {
    let location = CLLocationCoordinate2DMake(37.332077, -37.332077)
    let region = MKCoordinateRegion(center: location, latitudinalMeters: 1000, longitudinalMeters: 1000)
    mapSnapshotOptions.region = region
    print("a")
    mapSnapshotOptions.scale = UIScreen.main.scale
    mapSnapshotOptions.size = CGSize(width: 300, height: 300)
    mapSnapshotOptions.showsBuildings = true
    mapSnapshotOptions.showsPointsOfInterest = true

    snapShotter = MKMapSnapshotter(options: mapSnapshotOptions)
    print("b")
    var newImage: UIImage?
    self.snapShotter.start { (snapshot, error) -> Void in
        print("c")
        if error == nil {
            let image = snapshot!.image.withRenderingMode(.alwaysOriginal)
            var imageview = UIImageView(frame: CGRect(x: 30, y: 30, width: 300, height: 300))
            var label = UILabel()
            label.frame = CGRect(x: 0, y: 1, width: 30, height: 30)
            label.textAlignment = .center
            label.font = UIFont.boldSystemFont(ofSize: 12)
            label.textColor = UIColor.gray
            label.text = "my-text"
            imageview.addSubview(label)
            imageview.image = image
            newImage = image
            print(newImage)
            completion(newImage)
        } else {
            print("error")
            completion(nil)
        }

    }
    print("d")
}
getSnapshot(lat: 0, lon: 0) { image in
    DispatchQueue.main.async {
        self.imageView.image = image
    }
}

这是最常被问到的问题之一:。我没有失望。。。在else块中调用完成。。。否则它将永远留在记忆库中,我错过了那一点。不知道为什么当人们只是想帮助别人的时候,人们会否决正确的答案。。。不知道为什么。。。但是别担心。。。如果你正在学习,我没有投票,但请注意,这已经被询问和回答了100多次。拥有3000名代表,您有权“投票以重复方式关闭”-使用它!我知道有人问过这个问题。但如果我认识他们,我会给出答案,而不是否决或结束投票,这样他们就不会在漫长旅程的开始感到沮丧。我知道我是初学者时的感受。