在CoreData中更新实体时,是否需要使用setValue(_:forKey:)
,或者您可以使用默认的setter设置值?
someEntity.setValue("Bob", forKey: "Name")
VS
someEntity.name = "Bob"
第一种方法触发KVC,第二种方法不触发(正确吗?)。
接受的答案确认以上内容不正确。默认情况下,@ NSManaged在Swift属性上启用KVC。
托管对象上下文是否无法识别更改?使用默认的setter有什么缺点吗?我无法在任何文档中找到明确的答案。我的测试显示它运作得很好,但有些东西我不知道将来会再次咬我吗?
我在任何文档中找到的最接近的答案来自Key-Value Coding Programming Guide 键值编码与Swift
默认情况下,从NSObject或其子类之一继承的Swift对象是符合其属性的键值编码。而在Objective-C中,属性的访问器和实例变量必须遵循某些模式,Swift中的标准属性声明会自动保证这一点。
答案 0 :(得分:5)
不正确,两种方法都会触发KVC
。
setValue(:forKey)
是NSManagedObject
NSManagedObject
属性的@NSManaged
子类。属性@NSManaged
启用 KVC。两种方法都做同样的事情。
您甚至可以在setValue(:forKey)
子类中使用NSManagedObject
,但建议使用点表示法(并且更方便,更不容易出错)。
答案 1 :(得分:2)
NSManagedObject没有实体属性:实体类型不是对象类型,实体属性不是属性。相反,实体是一个神话(它们基本上只是一个标签),并且必须通过发送到NSManagedObject的KVC访问属性。
如果你没有使用自动类生成,那么你可以所有。
在Objective-C中,一个使事情更有效的解决方案是NSManagedObject上的一个类别,将实体属性定义为@dynamic
,这意味着Core Data将合成一个特殊的setter和getter来使用KVC < em> for you。
现在,情况甚至更好:编译器为每个实体类型生成一个NSManagedObject子类,其属性标记为Swift @NSManaged
,Objective-C @dynamic
。所以现在你有了实际的类,可以使用这些属性。这仍然只是一个为您生成正确的KVC呼叫的屏幕。
然而,这种符号的优点是显而易见的。如果你直接使用KVC,即使这种实体没有forKey:"wooblededoo"
属性,也没有什么能阻止你编写wooblededoo
(事实上,在过去,这是一个常见的错误)。但是如果使用类和属性,编译器会根据实体/属性描述将您限制为使用实际类的实际属性。