【发布时间】:2017-06-11 21:20:24
【问题描述】:
我需要您在 swift 中使用 GCD 的帮助,我刚开始使用这个工具,我有点困惑。因此,假设我有一个函数 foo() 可以拍照并将其保存到 var,在此函数内部还有另一个函数可以检查该照片上是否有人脸并返回真或假。接下来,当用户点击 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。由于 CoreImage 实现,我认为检测函数应该在主线程上。我只是做了这样的事情:
func foo(){
...
DispatchQueue.global().async {
self.checkingPhotoForFaces = self.detect(image: stillImage)
}
...
}
但问题是当用户在该按钮上点击太快时它不起作用,因为检测功能仍在处理中,所以我想我需要某种队列但我很困惑哪个。
顺便说一句。请不要执着于缺少上面的一些参数,我是即时写的,这不是重点
感谢您的帮助
【问题讨论】:
-
您需要在
detect()函数中添加一个完成闭包参数才能等到它完成。 -
我知道这是人脸检测,但我会认为任何与 Core Image 相关的东西都可以(并且确实)在 GPU 上运行。如果是这样,那岂不是抛弃了主线程的概念?
-
@shallowThought 好的,但我应该如何使用它?
-
@dfd 当我将检测函数发送到后台线程时,我得到“使用低 GPU 优先级进行后台渲染”并且它根本不起作用,不知道如何跳过它。在 global() 上,否则效果很好
标签: ios swift image concurrency photos