核心数据,自动更新导致问题的更改对象,并使事情变得更加混乱。
说我有这段代码:
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
的副本,这些副本将保持不变,所以我可以在以后用它做决策。
由于
答案 0 :(得分:3)
正如Michael的评论所述,trackToUpdate
是对NSManagedObject
实例的引用。指向同一对象的不同引用,...指向同一对象。因此,没有办法改变一个物体而使另一个物体保持不变,因为没有其他物体。 Swift通过意图来模糊引用,无论谁有真正的,非常聪明的想法。
正如你所说,你必须创建一个副本。 NSManagedObject
未实施NSCopying
协议。有充分的理由:如果实例引用其他实例(关系),您必须决定是否复制它们。这样做会导致复制整个图形的危险。不这样做,将您带回原始问题,即共享引用的实例。你必须做出决定。
将属性复制到简单字典中可能会更好。请记住,创建一个新实例,这将成为对象图的一部分。拥有“短时间”管理对象是一种代码气味(即使这个术语可能太难)。
但是,您可以创建一个新实例。然后通过-entity
获取对象的实体描述。实体描述具有属性-properties
,其中包含所有属性的列表。使用此方法,您可以迭代源属性并将其存储到新实例中。由于Objective-C的键值编码,可以在运行时执行此操作。