I have a bunch of code that sets Core Data relationships via the inverse instead of the "addWhateverObject" methods. This usually works well in all of my applications, but I have one app where the relationships are being lost when the NSManagedObject context is being saved.
My question is setting a relationship in Core Data via the relationship's inverse valid or do you have to use the accessor methods to add objects to the relationship?
Thanks!
Yes, using the inverse is valid. Core data does all of the appropriate updating for you when you do that. See the comments on this question Core Data To-Many Relationship Creating Duplicates When Adding Object to Parent Entity
Related
would like to ask for the community's suggestions.
I need a persistent store in my iOS app.
I have considered Core Data and SQLite and both are not ideal for the following reasons.
Core Data:
unable to model certain object relationships, such as Object A has a one-to-many relationship with NSString.
//Added:
unable to model a Dictionary(or map) as an attribute for a one-to-one relationship. i.e. Object A has a one-to-one relationship to Object B (and Object B behaves like a dictionary)
SQLite:
poor interface for schema management
no clean and elegant solution for data migration between schema versions
//Added:
unable to model a Dictionary(or map) as an attribute for a one-to-one relationship. i.e. Object A has a one-to-one relationship to Object B (and Object B behaves like a dictionary)
the persistent store has to be able to support search. If anyone can suggest ways to circumvent the problems, that would help too.
Based on your limited description, Core Data would work just fine. Core Data can easily do one to many relationships. No matter what technology that you use, you still need table to table (SQLite) or Object to Object (Core Data) relationships. Nothing is going to give you an Object to String relationship.
You can do Object A to Object B where Object B has only one property which happens to be a string.
After learning about relationships between entities in Core Data. I don't see the real reason for setting up relationship between two entities. They can be connected separately if one of the entities contains a property that can hold another entity by having a property of type NSManagedObject.
#property (nonatomic, strong ) NSManagedObject *AssetType;
This is a concept you must understand: Core Data is not a database but it is an object graph manager and, as a second functionality, offers persistence (e.g using for example a Sqlite store).
Said this, if you have two separated entities and you need to retrieve values based on the conditions that belong to the other entity, you need to run two requests and filter the results in memory. On the contrary if you set up a relationship you can just create a request wih a specific predicate and let Core Data to retrieve the correct results for you. In addition, through relationships you can access objects that belong to another entity as simple as accessing a property object. For example, the following snippet says that based on entityA I can access a property calles someRelationship that allows to retrieve one (or more) entities of type EntityB. If someRelationship has been set up as to-many you'll receive one or more EntityB entities.
entityB = entityA.someRelationship;
The real advice is to think in terms of objects graph!!!
Further reference: Core Data Overview by objc.io.
Update 1
The other big advantage is that relationships allow you to take advantage of deletion rules and, through inverse relationships, you are able to maintain the integrity of your graph.
See Relationships and Fetched Properties.
This question already has answers here:
Does every Core Data Relationship have to have an Inverse?
(8 answers)
Closed 8 years ago.
I'm used to using Hibernate in Java applications, and Many-To-One relationships are common there when for creating a link from ObjectA to a ReferenceObjectB. ReferenceObjectB may be an atomic class, that doesn't have any relationships to any other objects. ReferenceObjectB may be used in multiple other objects.
In my iOS app, I am using Core Data for the data model. I have created an ObjectA that has a one-to-many relationship to ReferenceObjectB, and created without an Inverse Relationship, as I want the relationship to act like the Many-To-One from Hibernate.
Seems to work. However, Xcode produces a warning: "Misconfigured Property: TimeItem.extraData should have an inverse" Is this a warning that should be heeded with Core Data, or is it just noise in this situation?
Warnings are there for a reason. The inverse of the relationship is used internally by Core Data to manage the data store contents as you add and (in particular) remove objects.
Generally, every relationship should have an inverse.
Not mandatory, but you'll have a warning. Read this post : http://shanecrawford.org/2008/49/a-warning-about-your-inverse-relationships/
Two-sides relationships needed to correctly manipulate objects when you creating them, or set one entity as property to other entity. Core data can automatically setting some relationships and you do not need do that manually.
Overall using one-side relationships is not always dangerous.
By example:
I have an entity User, and an entity Device.
User have a To Many relationship toward Device, called devices.
Device has the inverse of this relationship called user.
Now I collect, persist a bulk of devices from e.g. a network service, hydrate them into an NSSet, then I bound them to a particular user, so I do:
NSSet *collectedDevices = [API getSomeDevices];
someUser.devices = collectedDevices;
Will Core Data populate the inverse user relationship for each Device for me? Does it observe the setters for relationships?
Background:
I'm aware of the Core Data setters for setting collections, but I want to avoid using them. I'm actually reconstructing Core Data entities from JSON representations with KVC without hardcoded attributes, relationships, just enumerating their entity descriptions, and set matching values.
Yes, Core Data will set the inverse relationships whether you use properties or KVC or the Core Data specific methods such as -setPrimitiveValue:forKey:.
However, when it sets that inverse can be slightly variable. It can set it immediately in some situations and in others it may wait until the end of the run loop to set the inverse. As long as all of the objects being related are created against the same NSManagedObjectContext then the referential integrity will be maintained by Core Data.
Can a Core Data relationship be its own inverse relationship?
I have a generalized entity that is used to represent different types of objects. Some of these objects have to-many relationships to each other. Do I simply set the relationship as its own inverse, or create a new relationship with the same destination as the inverse?
Since Xcode gives you the option to set a relationship as its own inverse, I'm assuming it's okay, but would just like to make sure. Thanks in advance.
Yes there is no problem with this kind of relationship. You may always have links to objects in the class, even to the object itself.
Just in case you have to delete your objects from ManagedObjectContext you need to consider the deletion rules here https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdRelationships.html#//apple_ref/doc/uid/TP40001857-SW1.
But really no problem in general with your approach...