如何制作保持不变的核心数据对象的副本
Posted
技术标签:
【中文标题】如何制作保持不变的核心数据对象的副本【英文标题】:How to make a copy of a Core Data object, that remains untouched 【发布时间】:2016-11-16 04:58:52 【问题描述】:核心数据,自动更新导致问题的更改对象,并使事情变得比需要的更混乱。
假设我有这段代码:
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]
对象数组,然后它用please dont have updated
正确地更新了locality
的第一个元素。然后它保存这个对象。最后它会读取开头定义的tracksFound
数组。我原以为tracksFound
保持不变,对象tracksFound[0].locality
已更改为please dont have updated
。
如何阻止 Core Data 更新我的对象?我基本上想复制一份tracksFound
保持不变,这样我以后可以用它来做决策。
谢谢
【问题讨论】:
很简单,如果你没有调用 save() 方法意味着你的对象将保持不变。 代码let trackToUpdate = tracksFound[0]
获得对该元素的引用,而不是副本。因此,当您更改trackToUpdate
时,您实际上是在更改tracksFound[0]
。
@Karthick 不,除此之外很危险。
【参考方案1】:
正如迈克尔的评论中提到的,trackToUpdate
是对NSManagedObject
实例的引用。指向同一个对象的不同引用,……指向同一个对象。所以没有办法改变一个对象而让另一个保持不变,因为没有其他对象。斯威夫特通过意图混淆了引用,无论谁有这个非常非常聪明的想法。
正如你所说,你必须创建一个副本。 NSManagedObject
没有实现 NSCopying
协议。这样做有充分的理由:如果实例引用其他实例(关系),您必须决定是否也复制它们。这样做会导致复制整个图表的危险。不这样做,会让您回到最初的问题,即您共享一个引用的实例。你必须做出决定。
最好将属性复制到一个简单的字典中。请记住,创建一个新实例,这将成为对象图的一部分。拥有“短时间”托管对象是一种代码味道(甚至这个词可能太难了)。
但是,您可以创建一个新实例。然后通过-entity
获取对象的实体描述。实体描述有一个属性-properties
,它包含所有属性的列表。使用它,您可以遍历源属性并将其存储到新实例中。由于 Objective-C 的键值编码,可以在运行时执行此操作。
【讨论】:
感谢您的解释!以上是关于如何制作保持不变的核心数据对象的副本的主要内容,如果未能解决你的问题,请参考以下文章