[英]Swift UIApplication.delegate must be used from main thread only
Xcode is complaining when I try to set the appDelegate & context variables, required in order to use CoreData.当我尝试设置使用 CoreData 所需的 appDelegate 和上下文变量时,Xcode 抱怨。
Essentially, I would like to store the results of my Vision / CoreML image classification request into a Core Data database for offline analysis.本质上,我想将我的 Vision / CoreML 图像分类请求的结果存储到 Core Data 数据库中以进行离线分析。
Seen related threads to this, and tried a bunch.看到了与此相关的线程,并尝试了一堆。 Problem does not go away, and now (unknown to me!) the CoreData save errors after few hundred records.问题并没有消失,现在(我不知道!)CoreData 在几百条记录后保存错误。 I am hoping removing this issue altogether will solve the error problem or I can troubleshoot it later...我希望完全删除此问题将解决错误问题,或者我可以稍后对其进行故障排除...
This is specifically for debugging, and won't likely need CoreData when data analyses has finished.这专门用于调试,并且在数据分析完成后可能不需要 CoreData。
Tried putting the variable declarations right at the top of the ViewController class, with appending "!"尝试将变量声明放在 ViewController 类的顶部,并附加“!” as I know I will be setting them later.我知道我稍后会设置它们。 Tried putting the 2 lines in a DispatchQueue.main.async closure.尝试将 2 行放入 DispatchQueue.main.async 闭包中。
Tried wrapping these 2 lines inside a "DispatchQueue.main.async({ })" line, but then I can no longer reference the context on the "newItem" lines.尝试将这两行包装在“DispatchQueue.main.async({})”行中,但随后我无法再引用“newItem”行上的上下文。 Wrapping the whole section does not work either, probably as the CoreData cannot see / access the data within the image request(?)包装整个部分也不起作用,可能是因为 CoreData 无法查看/访问图像请求中的数据(?)
The code:编码:
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)
}
}
}
}
This is an annoying warning;这是一个烦人的警告; however, it seems to be there for a reason as iOS wants to avoid deadlocks(???).然而,它的存在似乎是有原因的,因为 iOS 想要避免死锁(???)。
Using Swift 3, here's what I've found is a safe way to manage Core Data + AppDelegate (your mileage may vary):使用 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
Hope this helps!希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.