Ios 乐观锁定失败

Ios 乐观锁定失败,ios,core-data,Ios,Core Data,是的,我当然在整个互联网上搜索过。 但我无法摆脱这个问题 我得到了两个实体名为: 邮政和大众邮政。 (几乎彼此重复) 当我获取帖子并更新它的属性时,比如numberoflikes,numberofcomments,这很好 但是当我获取PopularPost并尝试更新它的属性时,它会说 “乐观锁定失败” 获取、更新和保存实体的代码:“PopularPosts” let postpopFetch=NSFetchRequest(entityName:“PopularPosts”) postpopFet

是的,我当然在整个互联网上搜索过。 但我无法摆脱这个问题

我得到了两个实体名为: 邮政和大众邮政。 (几乎彼此重复)

当我获取帖子并更新它的属性时,比如numberoflikes,numberofcomments,这很好

但是当我获取PopularPost并尝试更新它的属性时,它会说 “乐观锁定失败”

获取、更新和保存实体的代码:“PopularPosts”

let postpopFetch=NSFetchRequest(entityName:“PopularPosts”)
postpopFetch.predicate=NSPredicate(格式:“id=%@”,postId)
让resultp=try?CoreDataManager.sharedInstance.managedObjectContext.fetch(PostOpFetch)
让resultdata=resultp为![公众人士]
对于resultDatap中的对象{
打印(object.numberOfHearts)
如果喜欢{
object.numberOfHearts=object.numberOfHearts+1
object.isLiked=true
}否则{
(object.numberOfHearts>0)?(object.numberOfHearts=object.numberOfHearts-1):(object.numberOfHearts=0)
object.isLiked=false
}
}
做{
请尝试CoreDataManager.sharedInstance.managedObjectContext.save()
打印(“已保存!”)
}将let错误捕获为NSError{
打印(“无法保存\(错误),\(错误.用户信息)”)
}

通常乐观锁定失败是由两个不同的托管对象上下文试图更改相同的数据引起的。我认为,如果您同时从不同线程不适当地访问上下文,那么即使在一个上下文中,也可能存在此问题。ManagedObjectContext是不是 线程安全,既不用于读取也不用于写入


我看到过这样一种情况,即从错误的线程访问managedObjectContext,并且在代码行上没有做任何错误时,会发生崩溃。我建议您仔细搜索您的代码,查找对主线程之外的核心数据的任何访问。您可以使用
[NSThread isMainThread]
检查您是否未在主线程上进行调试。

在我的例子中,这是由于使用
newBackgroundContext()
造成的

我有一个潜在的长时间运行的任务,该任务在应用程序进入后台时启动

即使它在再次使用应用程序之前完成,我发现在后台任务之后进行的所有保存都会失败


我通过对长时间运行的任务使用
viewContext
解决了这个问题。

您的核心数据堆栈是什么样子的?你有多少上下文?你有亲子关系吗?你用的是NSPersistent吗​容器?我在一个单例类中只维护了一个上下文。没有亲子关系。只有简单的2个实体。你总是在主线程上读写吗?@JonRose:有时涉及后台线程。我只得到一个托管对象上下文,我做了检查,以确保从主线程访问核心数据。但我还是遇到了同样的问题。光学锁定故障。怎么会??
let postpopFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "PopularPosts")
        postpopFetch.predicate = NSPredicate(format: "id = %@", postId)
        let resultp = try? CoreDataManager.sharedInstance.managedObjectContext.fetch(postpopFetch)
        let resultDatap = resultp as! [PopularPosts]

        for object in resultDatap {

            print(object.numberOfHearts)

            if like {
                object.numberOfHearts = object.numberOfHearts + 1
                object.isLiked = true
            }else{
                (object.numberOfHearts > 0) ? (object.numberOfHearts = object.numberOfHearts - 1) : (object.numberOfHearts = 0)
                object.isLiked = false
            }
        }

        do {
            try CoreDataManager.sharedInstance.managedObjectContext.save()
            print("saved!")
        } catch let error as NSError  {
            print("Could not save \(error), \(error.userInfo)")
        }