在核心数据中使用可变类型作为可转换属性的危险
至此,我们已经建立了数据模型。 现在介绍建立符合NSCoding的可变数据类型’ UnpredicatbleValue ‘的部分。 此数据类型具有一个变量存储的属性,称为Int类型的’ value ‘ 。 实现如下:
现在,我们可以为我们的TransformableContainer实体创建NSManagedObject子类。 该类的实现如下:
现在,请仔细阅读以下说明。
注意 :如果将托管对象引用的值/对象替换为全新的值/对象 ,则Core Data会将托管对象视为已更改。 据说, 管理对象有未决的更改 。 现在,在上下文中调用save时,将保存下一次具有待处理更改的受管对象。
但是,如果您有一个由托管对象指向的对象,并且更改了objects 变量 (更改了对象的状态),则Core Data不知道它已被更改 。 因此, 托管对象未标记为具有挂起的更改 。 下次在上下文中调用保存时,将不会保存此类对象。
如果您已阅读以上说明,我们现在可以通过实际测试来证明这一点。 让我们打开ViewController.swift并编写以下代码:
如您所见,我们在viewDidLoad()中执行以下操作
- 从appDelegate的persistentContainer获取viewContext 。
- 在第一个do块中,我们将TransformableContainer插入到viewContext中。 该值设置为3 ,然后在viewContext上执行保存。
- 在第二个do块中,我们获取TransformableContainer。 将值更改为4并执行保存。
- 在第三个do块中,我们获取TransformableContainer。 打印值。
- 在第四个do块中,我们获取TransformableContainer。 我们从上下文中删除它并执行保存。
现在我们认为将值更改为4并执行保存后,应该将4保存为该值。 显然不是这样。 当该值实际为3时,我们会感到无礼。在控制台中,我们将获得以下日志。
值设为3
值从3变为4
transformableContainer.transformableAttribute.value:3
在考虑使用可变形属性时,请记住上面的注释 。 如果将可变类型用作可转换属性,则将面临危险。
您可以通过为Transformable属性使用非可变类型来避免这种情况。 如果不完全替换对象,则无法更改该值。 如果替换了对象,CoreData会知道它已更改,并将拥有的托管对象标记为具有挂起的更改。 下次在上下文上调用保存时,它将被保存。 因此,基本上,我们如下更改UnpredicatbleValue的实现:
现在我们受到了编译器的保护。 每当我们更改值时,都会抱怨无法更改值。 我们唯一的选择是使用具有新值集的较新对象替换较旧的对象。 因此,Core Data能够跟踪更改,因此我们可以避免之前遇到的危险。
希望这可以帮助。
- 无法用开发人员configuration文件部署发行版本
- Alamofire 4 Swift 3 ParameterEncoding自定义
- iOS / Swift:viewDillLoad和viewWillAppear之间的函数我应该查询一个数据库?
- iOS Core将CPTAxisLabel与CPTPlotalignment
- iOS 7没有调用supportedInterfaceOrientations
- uiscrollview放大和缩小function无法正常工作
- 在更新到iOS 7之后,iOS 6中的所有视图都向上移动,并被导航栏隐藏
- 如果同时触发滑动手势和后退button,则导航栏会变得时髦
- 迅速发展的世界:SE-0185综合了可量化和可哈希化的一致性