Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 959
Clay Ellis Avatar asked Feb 11 '18 19:02

Clay Ellis


People also ask

What is CoreData in Swift IOS?

Overview. Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.

What is CoreData in IOS?

Core Data is a framework that you use to manage the model layer objects in your application. It provides generalized and automated solutions to common tasks associated with object life cycle and object graph management, including persistence.

Is CoreData thread safe?

Core Data is designed to work in a multithreaded environment. However, not every object under the Core Data framework is thread safe. To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization.

How do I get Data from CoreData?

Fetching Data From CoreData We have created a function fetch() whose return type is array of College(Entity). For fetching the data we just write context. fetch and pass fetchRequest that will generate an exception so we handle it by writing try catch, so we fetched our all the data from CoreData.


2 Answers

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.

like image 64
vadian Avatar answered Oct 05 '22 01:10

vadian


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.

like image 20
matt Avatar answered Oct 05 '22 01:10

matt