核心数据在更新旧数据时创建新对象

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (3)

首先,我不认为这是重复的:在核心数据中更新对象值也是在创建一个新对象(它在Obj-C中,并且每次它们都在调用时调用insertNewObject。)

背景信息:我学习了如何使用Ray Wenderlich书中的CoreData,并在编写此代码时参考了它。如果你有这本书的话,我按照第3章所述滚动我自己的自定义堆栈。如果需要,我可以显示此代码。

队列是我正在尝试更新的实体。

它有1个属性:name - String

和1对多关系:任务:任务 我的CoreData逻辑位于包含managedContext的Struct中。

我有一个基本的find / create函数来创建一个Queue对象。这有效。它创建1个且只有1个对象。

func findOrCreateMainQueue() -> Queue? {
    let queue = Queue(context: managedContext)
    queue.name = "Queue32"

    let queueFetch: NSFetchRequest<Queue> = Queue.fetchRequest()
    queueFetch.predicate = NSPredicate(format: "%K == %@", #keyPath(Queue.name), "Queue32" as CVarArg)
    do {
        let results = try managedContext.fetch(queueFetch)
        print(results.count)

        if results.count > 0 {
            return results.first!
        } else {
            try managedContext.save()
        }

    } catch let error as NSError {
        print("Fetch error: \(error) description: \(error.userInfo)")
    }

    return nil
}

(正如你在queue.name后缀中看到的那样,我尝试了很多不同的东西。)

我已经尝试了几乎我能想到的一切:

此代码基本上是从以下位置复制/粘贴的:如何更新已在Swift中保存的CoreData条目?

func addTaskToMainQueue2(task: Task) {
    let queueFetch: NSFetchRequest<Queue> = Queue.fetchRequest()
    queueFetch.predicate = NSPredicate(format: "%K == %@", #keyPath(Queue.name), "Queue32" as CVarArg)
    do {
        let results = try managedContext.fetch(queueFetch)
        print(results.count)

        if results.count > 0 {

            var tasks = results[0].tasks?.mutableCopy() as? NSMutableOrderedSet
            tasks?.add(task)
            results[0].setValue(tasks, forKey: "tasks")
        }

    } catch let error as NSError {
        print("Fetch error: \(error) description: \(error.userInfo)")
    }

        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Save error: \(error),description: \(error.localizedDescription)")
        }


}

这导致使用“Queue32”名称创建第二个Queue对象。

这是我尝试的另一件事:

func addTaskToMainQueue(task: Task) {
    if var queue = findOrCreateMainQueue() {
        var tasks = queue.tasks?.mutableCopy() as? NSMutableOrderedSet
        tasks?.add(task)
        queue.tasks = tasks
        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Save error: \(error),description: \(error.localizedDescription)")
        }

    }
}

为了空间,我不会为我尝试过的其他东西添加代码。

  • 我尝试过使用find / create函数并在该方法中进行更新。
  • 我已经尝试将队列保存为本地对象并将其传递给addTask函数,这也会导致重复。
  • 如果我传入Task或在addTask函数中创建一个也没关系。

我开始相信我的问题是我的dataModel文件中的问题,因为我已经尝试了一些“如何在线更新核心数据对象”教程,每次都得到相同的结果。

每当我尝试更新对象时都会调用awakeFromInsert()。不确定是否应该发生这种情况。

在我的应用程序更新工作的其他地方。例如,如果我向任务添加子任务。它工作正常。但是,如果我想更改名为Project的另一个实体的名称,则该对象将重复。(项目具有获取的id属性,然后更改name属性。)

先感谢您。我一直把头发拉了几个小时。

提问于
用户回答回答于

我承认没有阅读所有代码,但是如果你创建一个像这样的新托管对象

let queue = Queue(context: managedContext)

然后它将被添加到,managedContext并将在某个时候保存到磁盘。所以这段代码

if results.count > 0 {
    return results.first!
} else {
    try managedContext.save()
}

queue先前创建的对象无关,因为即使在results.count> 0时它也会被保存,尽管稍后会被保存。所以这意味着你必须删除queuefetch成功时感觉不必要,最好等待创建它

if results.count > 0 {
    return results.first!
} else {
    let queue = Queue(context: managedContext)
    queue.name = "Queue32"
    try managedContext.save()
}

关闭主题但我看到如果创建了一个新对象而不是提取,则返回nil,这是有意的吗?

扫码关注云+社区

领取腾讯云代金券