ios – 意外的核心数据多线程违规

前端之家收集整理的这篇文章主要介绍了ios – 意外的核心数据多线程违规前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用苹果的并发核心数据调试器.

-com.apple.CoreData.ConcurrencyDebug 1

有时候我得到__Multithreading_Violation_AllThatIsLeftToUsIsHonor__,即使我几乎肯定线程没有被违反.

这是发生异常的代码的一部分(代码是扩展NSManagedObject的协议的一部分):

public static func find(arrayBy predicate: NSPredicate,sort: [NSSortDescriptor] = [],limit: Int? = nil) -> [Self] {
    let fetchRequest = NSFetchRequest<Self>(entityName: "\(Self.self)")
    fetchRequest.predicate = predicate
    fetchRequest.sortDescriptors = sort

    do {
        return try Context.current.fetch(fetchRequest) // Exception!!!
    } catch let error {
        Logger.fatal("Failed to perform fetch: \(error)")
        return []
    }
}

代码在上下文的执行:块中执行.

这里是线程信息:

和调试器信息来确认执行是否正确执行NSManagedContext:

(lldb) po Context.current
<StoreContext: 0x7f854b556610>

实体名称被成功提取

po fetchRequest.entityName!
"Position"

谓词由纯String对象构成(根本不使用任何托管对象):

(lldb) po fetchRequest.predicate!
ANY employees.company.id == "282372"

在这种情况下,完全不使用排序描述符:

po fetchRequest.sortDescriptors!
0 elements

限制完全被忽略.

我失踪了什么有人有什么想法吗?

编辑:

为了澄清,Context.current是在调度块之前设置的:

Context.current = managedObjectContext
managedObjectContext.performAndWait {
   //...
}

您可以在截图上看到Thread 13在Queue上运行:NSManagedObject 0x7f854b556610(serial).而且,当异常发生时Context.current返回< StoreContext:0x7f854b556610&gt ;.通过查看内存地址,很容易得出结论块正在正确的队列中执行.

解决方法

将“当前”背景环境存储在全局状态是不好的做法.我不能指出你的代码在哪里搞错了,但是当涉及多线程时,全局状态会发生意想不到的事情.更改您的查找功能以接受上下文作为参数.这将避免使用任何全局状态,并且可能会解决您的问题.

猜你在找的iOS相关文章