CoreData 在 Swift 中是必要的 setValue(_:forKey:) 吗?

Posted

技术标签:

【中文标题】CoreData 在 Swift 中是必要的 setValue(_:forKey:) 吗?【英文标题】:CoreData is setValue(_:forKey:) necessary in Swift? 【发布时间】:2018-02-11 19:14:25 【问题描述】:

更新CoreData中的实体时,是否需要使用setValue(_:forKey:),还是可以直接使用默认的setter设置值?

someEntity.setValue("Bob", forKey: "Name")

对比

someEntity.name = "Bob"

第一种方法触发 KVC,第二种方法不触发(对吗?)。

接受的答案确认上述内容不正确。 @NSManaged 默认在 Swift 属性上启用 KVC。

那么托管对象上下文会无法识别更改吗?使用默认设置器有什么缺点吗?我在任何文档中都找不到明确的答案。我的测试表明它工作得很好,但是有什么我不知道的东西将来会回来咬我吗?

我在任何文档中找到的最接近的答案来自 Key-Value Coding with Swift

下的 Key-Value Coding Programming Guide

默认情况下,从 NSObject 或其子类之一继承的 Swift 对象的属性符合键值编码。而在 Objective-C 中,属性的访问器和实例变量必须遵循某些模式,而 Swift 中的标准属性声明会自动保证这一点。

【问题讨论】:

【参考方案1】:

不正确,两种方法都会触发KVC

setValue(:forKey)NSManagedObject 的泛型方法 点表示法适用于访问@NSManaged 属性的NSManagedObject 子类。属性@NSManaged 启用 KVC。

两种方法都做同样的事情。

您甚至可以在NSManagedObject 子类中使用setValue(:forKey),但建议(更方便且不易出错)使用点表示法。

【讨论】:

谢谢,在阅读了 KVC 指南后,我意识到我的假设是不正确的。感谢您确认。 嘿@vadian 有没有办法直接将 ManageObject 添加到 CoreData,实际上我正在尝试将 api 响应映射到 My ManageModel 并将其直接存储到磁盘中 map api response to My ManageModel是什么意思?【参考方案2】:

NSManagedObject 没有实体属性:实体类型不是对象类型,实体属性也不是属性。相反,实体有点像神话(它们基本上只是一个标签),并且必须通过发送到 NSManagedObject 的 KVC 访问属性。

如果您不使用自动类生成,那将是所有您可以做到的。

在 Objective-C 中,让事情更好地工作的一个解决方案是 NSManagedObject 上的一个类别,将实体属性定义为@dynamic,这意味着 Core Data 将合成一个特殊的 setter 和 getter 以使用 KVC 为你

现在,事情变得更好了:编译器为每个实体类型生成一个 NSManagedObject 子类,其属性标记为 Swift @NSManaged,Objective-C @dynamic。所以现在你有了实际的类,并且可以使用这些属性。这仍然只是为您生成正确 KVC 调用的屏幕。

然而,这种表示法的优势是显而易见的。如果你直接使用 KVC,没有什么能阻止你编写 forKey:"wooblededoo",即使这种实体没有 wooblededoo 属性(事实上,在过去,这是一个常见的错误)。但是如果你使用类和属性,编译器会限制你使用基于实体/属性描述的实际类的实际属性。

【讨论】:

感谢您的深入回答!我接受@vadian 的回答,因为它是一个更直接的回答。不过,感谢您的意见。 "NSManagedObject 没有实体属性:实体类型不是对象类型,实体属性也不是属性。相反,实体是一个神话(它们基本上只是一个标签) ,并且必须通过发送到 NSManagedObject 的 KVC 访问属性。” - 大吃一惊。感谢@matt 的精彩回答

以上是关于CoreData 在 Swift 中是必要的 setValue(_:forKey:) 吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 swift 从 CoreData 创建 PDF(或其他可查看格式,例如 .docx)

Swift/IOS/CoreData:如何在自动生成的 CoreData 类中将 var 定义为枚举类型?

在 CoreData (Swift) 中存储位置

在 Swift 中使用 NSPredicate 对 CoreData 结果进行排序

这个 CoreData 如何在 swift 3 中获取?

如何在重置之前向日志添加值(CoreData 和 Swift)