ios - 如何在 Swift 4.0 中使用 DispatchQueue

标签 ios iphone swift grand-central-dispatch coreml

我制作了一个使用 CoreML 的图像识别应用程序。从 UI 方面来看,我想在选择图像后返回主视图并在函数 detect() 完成后显示结果。但是,即使我使用 DispatchQueue.main 它也总是同时显示结果和主视图。如果我在 detect() 中使用 DispatchQueue.main,它就可以工作。但我认为它不应该在那里。 还有一个问题是 SVProgressHUD.show() 不起作用。

import UIKit
import CoreML
import Vision
import SVProgressHUD

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var imageView: UIImageView!

    @IBOutlet weak var cameraButton: UIBarButtonItem!
    let imagePicker = UIImagePickerController()

    override func viewDidLoad() {
        super.viewDidLoad()
        imagePicker.delegate = self


    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        cameraButton.isEnabled = false
        SVProgressHUD.show()



        if let userPickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage{

            imageView.image = userPickedImage
            imagePicker.dismiss(animated: true, completion: nil)


            let userPickedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
            guard let ciImage = CIImage(image: userPickedImage) else {
                fatalError("WRONG")
            }
            detect(image: ciImage)
        } 
    }

    func detect(image: CIImage){

        guard let model = try? VNCoreMLModel(for: Inceptionv3().model) else {
            fatalError("Loading CoreML Model Failed")
        }

        let request = VNCoreMLRequest(model: model) { (request, error) in
            guard let results = request.results as? [VNClassificationObservation] else{
                fatalError("Model failed to process image")
            }
            if let firstResult = results.first {
                let r = firstResult.identifier.split(separator: ",")
                DispatchQueue.main.async {
                    self.cameraButton.isEnabled = true
                    SVProgressHUD.dismiss()
                    self.navigationItem.title = r.last?.description
                }
            }
        }


        let handler = VNImageRequestHandler(ciImage: image)
        do{
            try handler.perform([request])
        }
        catch {
            print(error)
        }

    }

    @IBAction func cameraTapped(_ sender: UIBarButtonItem) {
        imagePicker.sourceType = .savedPhotosAlbum
        imagePicker.allowsEditing = false
        present(imagePicker, animated: true, completion: nil)
    }
}

最佳答案

如果我理解正确你的问题,你可以改变如下:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    cameraButton.isEnabled = false
    SVProgressHUD.show()

    if let userPickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage{
        imageView.image = userPickedImage
        imagePicker.dismiss(animated: true) {
        guard let ciImage = CIImage(image: userPickedImage) else {
            fatalError("WRONG")
        }
        self.detect(image: ciImage)
        }
    }
}

关于ios - 如何在 Swift 4.0 中使用 DispatchQueue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47491620/

相关文章:

ios - 如何通过 uitableviewCell 中的单击操作更改 2 个 UIButton 图像

ios - 尝试呈现其 View 的 UINavigationController

swift - UISegmentedControl 的 setEnabled 没有不同的样式

ios - 具有执行功能和 UI 更新的重复动画

android - React Native - 为什么我们在 CameraRoll.getPhotos() 中使用 after 属性?

iphone - 将 UIAlertView 添加到 UIScrollView

iphone - 更改设备音量

iphone - fmdb 在运行更新查询时锁定应用程序

ios - 解析 : How can I update all rows with the same key value

iphone - 为什么应用内购买沙盒总是询问 "Verification Required"?