如何为下面的异步函数编写回调函数

时间:2017-09-13 15:31:13

标签: ios swift asynchronous swift3 callback

我有一个我正在使用的功能。我想要来自该异步函数的数据,但如果我尝试使用fullResolutionImageData函数之外的数据,它就会出现nil。所以我必须写一个回调。但我不知道如何编写回调。有人可以告诉我如何为下面的异步函数编写回调,以便我可以在其他地方访问数据。你能告诉我如何编写回调,以便我可以访问fullResolutionImageData异步函数之外的文件。

public func fullResolutionImageData(completion: @escaping (Data?) -> ()) {
    SharedQueues.imageProcessingQueue.addOperation { [path] in
        let data = try? Data(contentsOf: URL(fileURLWithPath: path))
        DispatchQueue.main.async {
            completion(data)
        }
    }
}

在我的视图控制器中,我有一个使用此功能的动作

class ViewController: UIViewController{
    func buttonAction(sender:UIButton!){
        var photos2: [ImageSource]?
        var files : [Data] = []
        let _ = self.photos2?.map ({completion: path in
            path.fullResolutionImageData{ data in
                files.append(data) --> (prints 2)
            }
        })
        print("(files.count)") --> (prints 0 How do I write callback?)
    }
}

1 个答案:

答案 0 :(得分:0)

你需要的只是Dispatch Group。

func buttonAction(sender:UIButton!){
        var photos2: [ImageSource]?
        var files : [Data] = []

        let myGroup = DispatchGroup()
        let _ = self.photos2?.map ({completion: path in
            myGroup.enter()
            path.fullResolutionImageData{ data in
                files.append(data) --> (prints 2)
                myGroup.leave()
            }
        })

        myGroup.notify(queue: DispatchQueue.main) { // 2
            print("(files.count)")
        }
    }

一点点解释:

Dispatch groups用于监视多个异步任务的完成情况。就像在你的情况下从你在后台线程上执行的文件路径中获取数据一样。

需要注意的事项:

进入该组的每一项任务都应该离开该组,无论该组是否成功。如果任何进入该组的任务未能退出,则线程将永远被阻止。因此,请确保fullResolutionImageData始终执行完成块!

修改

最后正如David在评论中指出的那样,使用foreach循环然后使用map是有意义的,如果你丢弃结果

因此使用

func buttonAction(sender:UIButton!){
        var photos2: [ImageSource]?
        var files : [Data] = []

        let myGroup = DispatchGroup()
        photos2?.forEach{ path in
             myGroup.enter()
             path.fullResolutionImageData{ data in
                 files.append(data) --> (prints 2)
                 myGroup.leave()
             }
        }

        myGroup.notify(queue: DispatchQueue.main) { // 2

        }
    }