如何制作核心数据对象的副本,保持不变

时间:2016-11-16 04:58:53

标签: ios objective-c swift core-data swift3

核心数据,自动更新导致问题的更改对象,并使事情变得更加混乱。

说我有这段代码:

let fetchRequest = Track.fetchRequest()

//update it
do {
    let tracksFound = try self.managedObjectContext.fetch(fetchRequest) as! [Track]
    print("retrieved")

    let trackToUpdate = tracksFound[0]

    trackToUpdate.locality = "please dont have updated"

    do {
        try self.managedObjectContext.save()
        print("saved")
    }
    catch {
        fatalCoreDataError(error)
    }

    for t in tracksFound {
        print(t.locality)
    }
}
catch {
    fatalCoreDataError(error)
}

您可以看到它抓取[Track]对象数组,然后使用locality正确更新第一个元素please dont have updated。然后它保存这个对象。最后,它读取了开头定义的tracksFound数组。我原本期望tracksFound保持不变,对象tracksFound[0].locality已更改为please dont have updated

如何阻止核心数据更新我的对象?我基本上想制作一份tracksFound的副本,这些副本将保持不变,所以我可以在以后用它做决策。

由于

1 个答案:

答案 0 :(得分:3)

正如Michael的评论所述,trackToUpdate是对NSManagedObject实例的引用。指向同一对象的不同引用,...指向同一对象。因此,没有办法改变一个物体而使另一个物体保持不变,因为没有其他物体。 Swift通过意图来模糊引用,无论谁有真正的,非常聪明的想法。

正如你所说,你必须创建一个副本。 NSManagedObject未实施NSCopying协议。有充分的理由:如果实例引用其他实例(关系),您必须决定是否复制它们。这样做会导致复制整个图形的危险。不这样做,将您带回原始问题,即共享引用的实例。你必须做出决定。

将属性复制到简单字典中可能会更好。请记住,创建一个新实例,这将成为对象图的一部分。拥有“短时间”管理对象是一种代码气味(即使这个术语可能太难)。

但是,您可以创建一个新实例。然后通过-entity获取对象的实体描述。实体描述具有属性-properties,其中包含所有属性的列表。使用此方法,您可以迭代源属性并将其存储到新实例中。由于Objective-C的键值编码,可以在运行时执行此操作。