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 定义为枚举类型?