Clay Ellis
Clay Ellis

Reputation: 5330

CoreData is setValue(_:forKey:) necessary in Swift?

When updating an entity in CoreData, is it necessary to use setValue(_:forKey:), or can you just set the value using the default setter?

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

vs.

someEntity.name = "Bob"

The first method triggers KVC, the second doesn't (correct?).

The accepted answer confirms that the above is incorrect. @NSManaged enables KVC on Swift properties by default.

So will the managed object context fail to recognize the changes? Are there any drawbacks to using the default setter? I can't find a definitive answer in any documentation. My tests show that it works just fine, but is there something that I don't know that'll come back to bite me in the future?

The closest answer I've found in any documentation is from the Key-Value Coding Programming Guide under Key-Value Coding with Swift

Swift objects that inherit from NSObject or one of its subclasses are key-value coding compliant for their properties by default. Whereas in Objective-C, a property’s accessors and instance variables must follow certain patterns, a standard property declaration in Swift automatically guarantees this.

Upvotes: 10

Views: 2161

Answers (2)

matt
matt

Reputation: 535546

NSManagedObject has no entity properties: an entity type is not an object type, and an entity attribute is not a property. Instead, the entities are something of a myth (they are basically just a label), and the attributes must be accessed through KVC sent to an NSManagedObject.

If you didn't use automatic class generation, that would be all you could do.

In Objective-C, one solution to make things work a bit more nicely would be a category on NSManagedObject defining the entity properties as @dynamic, meaning that Core Data will synthesize a special setter and getter to use KVC for you.

Nowdays, things are even better: the compiler generates an NSManagedObject subclass for each entity type, whose properties are marked Swift @NSManaged, Objective-C @dynamic. So now you have actual classes and can use those properties instead. This is still nothing but a screen to generate the correct KVC calls for you.

The advantage of this notation, however, is obvious. If you use KVC directly, nothing prevents you from writing forKey:"wooblededoo" even though there is no wooblededoo attribute for this kind of entity (and indeed, in the old days this was a common mistake to make). But if you use classes and properties, the compiler confines you to using the actual properties for the actual classes based on the entity/attribute descriptions.

Upvotes: 4

vadian
vadian

Reputation: 285150

Not correct, both methods trigger KVC.

  • setValue(:forKey) is a generic method of NSManagedObject
  • Dot notation is for NSManagedObject subclasses accessing @NSManaged properties. The attribute @NSManaged enables KVC.

Both methods do the same thing.

You can even use setValue(:forKey) in NSManagedObject subclasses but it's recommended (and more convenient and less error-prone) to use dot notation.

Upvotes: 9

Related Questions