微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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 ;.通过查看内存地址,很容易得出结论块正在正确的队列中执行.

解决方法

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

原文地址:https://www.jb51.cc/iOS/330566.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐