必须仅从主线程

时间:2017-12-02 22:37:40

标签: swift multithreading core-data

当我尝试设置appDelegate&时,XCode抱怨上下文变量,是使用CoreData所必需的。

基本上,我想将Vision / CoreML图像分类请求的结果存储到Core Data数据库中以进行离线分析。

看到相关的线程,并尝试了一堆。问题不会消失,现在(我不知道!)CoreData在几百条记录后保存错误。我希望完全删除这个问题将解决错误问题,或者我可以在以后解决它...

这是专门用于调试的,并且在数据分析完成后不太可能需要CoreData。

尝试将变量声明放在ViewController类的顶部,并附加"!"据我所知,我将在以后设置它们。尝试将2行放在DispatchQueue.main.async闭包中。

尝试将这两行包裹在" DispatchQueue.main.async({})"但是我不能再引用" newItem"线。包装整个部分也不起作用,可能是因为CoreData无法查看/访问图像请求中的数据(?)

代码:

func processCameraBuffer(sampleBuffer: CMSampleBuffer) {

    let coreMLModel = Inceptionv3()

    if let model = try? VNCoreMLModel(for: coreMLModel.model) {
        let request = VNCoreMLRequest(model: model, completionHandler: { (request, error) in
            if let results = request.results as? [VNClassificationObservation] {
                var counter = 1

                for classification in results {

                        let timestamp = NSDate().timeIntervalSince1970

                    // Purple Error is here
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    let context = appDelegate.persistentContainer.viewContext

                    let newItem = NSEntityDescription.insertNewObject(forEntityName: "Predictions", into: context)
                        newItem.setValue(classification.confidence, forKey: "confidence")
                        newItem.setValue(classification.identifier, forKey: "identifier")
                        newItem.setValue(counter, forKey: "index")
                        newItem.setValue(timestamp, forKey: "timestamp")
                        newItem.setValue("inceptionv3", forKey: "mlmodel")
                        print("counter: \(counter) \(classification.identifier)")
                        do {
                            try context.save()
                        } catch {
                            print("CoreData Save error")
                            print(error.localizedDescription)
                        }
                    counter += 1
                }
            }
        })

            if let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
                let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:])
                do {
                    try handler.perform([request])
                } catch {
                    print(error.localizedDescription)
                }
            }
    }
}

1 个答案:

答案 0 :(得分:0)

这是一个令人讨厌的警告;但是,这似乎是有原因的,因为iOS希望避免死锁(???)。

使用Swift 3,这是我管理Core Data + AppDelegate的安全方法(您的里程可能会有所不同):

DispatchQueue.main.async {
    if let app = UIApplication.shared.delegate as? AppDelegate {
        app.managedObjectContext.performAndWait {
            // .. Core Data work here
            // .. context.save() 
        } // app.managedObjectContext.performAndWait
    } // if let app = UIApplication.shared.delegate as? AppDelegate
} // DispatchQueue.main.async

希望这会有所帮助!