我需要你迅速帮助GCD,我刚开始使用这个工具,我有点困惑。所以假设我有一个函数foo()拍摄照片并将其保存到var,在这个函数中还有另一个函数来检查该照片上是否有面孔并返回true或false。接下来,当用户点击usePhotoFromPreview按钮时,只要该照片上没有任何面孔,它就会通过自定义委托保存照片:
var image: UIImage?
var checkingPhotoForFaces: Bool?
func foo(){
let videoConnection = imageOutput?.connection(withMediaType: AVMediaTypeVideo)
imageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (imageDataSampleBuffer, error) -> Void in
if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) {
image = UIImage(data: imageData)
self.checkingPhotoForFaces = self.detect(image: image)
}
})
}
func detect(image: UIImage) -> Bool{
.....
}
func usePhotoFromPreview(){
self.dismiss(animated: true, completion: {
if self.checkingPhotoForFaces == false{
self.delegate?.takenPhoto(photo: self.image!)
print("photo taken")
}else{
self.delegate?.takenPhoto(photo: nil)
print("no photo taken")
}
})
}
所以现在是棘手的部分,我想让异步执行检测功能,只有当它完成时才执行usePhotoFromPreview。检测func我想应该在主线程上因为CoreImage实现。我只是做了这样的事情:
func foo(){
...
DispatchQueue.global().async {
self.checkingPhotoForFaces = self.detect(image: stillImage)
}
...
}
但问题是,当用户点击那个按钮太快时,它将无法正常工作,cuz检测func仍在处理,所以我认为我需要某种队列,但我很困惑哪一个。
顺便说一句。拜托,不要紧紧抓住上面缺少的一些参数,我是在飞行中写的,这不是重点
感谢您的帮助
答案 0 :(得分:0)
如上所述更改检测:
func detect(image: UIImage, completion: ()->(detectedFaces: Bool)){
//.....
completion(true|false)
}
然后
if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer) {
image = UIImage(data: imageData)
self.detect(image) { detectedFaces in
self.checkingPhotoForFaces = detectedFaces
//Enable button?
}
}