-1

此示例说明如何使用 coreData 异步提取数据。如果您在没有方案“-com.apple.CoreData.ConcurrencyDebug 1”的情况下运行程序所有工作,但如果您打开方案“-com.apple.CoreData.ConcurrencyDebug 1”我们会得到运行时错误。为什么会发生这种情况我不知道

(我没有违反这些条款)来自苹果文档

Core Data 被设计为在多线程环境中工作。然而,并不是 Core Data 框架下的每个对象都是线程安全的。要在多线程环境中使用 Core Data,请确保:

托管对象上下文绑定到它们在初始化时关联的线程(队列)。

从上下文中检索的托管对象绑定到上下文所绑定的同一个队列。


Stack Trace

CoreData`+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:
    0x7fff23a8a65e <+0>: pushq  %rbp
    0x7fff23a8a65f <+1>: movq   %rsp, %rbp
->  0x7fff23a8a662 <+4>: ud2 

override func viewDidLoad() {
    super.viewDidLoad()
    do {
      let batchResult = try coreDataStack.managedContext.execute(batchUpdate) as! NSBatchUpdateResult
      print("Records updated \(batchResult.result!)")
    } catch let error as NSError {
      print("Could not update \(error), \(error.userInfo)")
    }

    let venueFetchRequest: NSFetchRequest<Venue> = Venue.fetchRequest()
    fetchRequest = venueFetchRequest

    asyncFetchRequest = NSAsynchronousFetchRequest<Venue>(fetchRequest: venueFetchRequest) {
      [unowned self] (result: NSAsynchronousFetchResult) in
      guard let venues = result.finalResult else {
        return
      }

      self.venues = venues
      self.tableView.reloadData()
    }

    do {
      guard let asyncFetchRequest = asyncFetchRequest else {
        return
      }
      try coreDataStack.managedContext.execute(asyncFetchRequest)
      // Returns immediately, cancel here if you want
    } catch let error as NSError {
      print("Could not fetch \(error), \(error.userInfo)")
    }
 }

4

1 回答 1

1

这是一个很好的收获。我希望答案能帮助更多。

我下载了代码并尝试了一下,在弄乱了一段时间后,我很确定这是 Apple 框架中的一个错误。看起来示例项目中的代码是正确的,但是并发检查仍然会标记它。我不知道这是否是因为代码实际上导致了并发违规,或者是否没有违规但标志有问题。

不幸的是,您所看到的只是现在发生的事情,并且无法在应用程序中修复——只有 Apple 可以解决它。这也是一个长期存在的问题,从几年前的这个答案中可以看出。我建议向Apple提交错误。

于 2020-08-03T16:45:35.100 回答