我有一个我正在使用的功能。我想要来自该异步函数的数据,但如果我尝试使用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?)
}
}
答案 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
}
}