Does every Core Data Relationship have to have an Inverse?

Viewed 62447

Let's say I have two Entity classes: SocialApp and SocialAppType

In SocialApp I have one Attribute: appURL and one Relationship: type.

In SocialAppType I have three Attributes: baseURL, name and favicon.

The destination of the SocialApp relationship type is a single record in SocialAppType.

As an example, for multiple Flickr accounts, there would be a number of SocialApp records, with each record holding a link to a person's account. There would be one SocialAppType record for the "Flickr" type, that all SocialApp records would point to.

When I build an application with this schema, I get a warning that there is no inverse relationship between SocialAppType and SocialApp.

 /Users/username/Developer/objc/TestApp/TestApp.xcdatamodel:SocialApp.type: warning: SocialApp.type -- relationship does not have an inverse

Do I need an inverse, and why?

8 Answers

In practice, I haven't had any data loss due to not having an inverse - at least that I am aware of. A quick Google suggests you should use them:

An inverse relationship doesn't just make things more tidy, it's actually used by Core Data to maintain data integrity.

-- Cocoa Dev Central

You should typically model relationships in both directions, and specify the inverse relationships appropriately. Core Data uses this information to ensure the consistency of the object graph if a change is made (see “Manipulating Relationships and Object Graph Integrity”). For a discussion of some of the reasons why you might want to not model a relationship in both directions, and some of the problems that might arise if you don’t, see “Unidirectional Relationships.”

-- Core Data Programming Guide

The better question is, "is there a reason not to have an inverse"? Core Data is really an object graph management framework, not a persistence framework. In other words, its job is to manage the relationships between objects in the object graph. Inverse relationships make this much easier. For that reason, Core Data expects inverse relationships and is written for that use case. Without them, you will have to manage the object graph consistency yourself. In particular, to-many relationships without an inverse relationship are very likely to be corrupted by Core Data unless you work very hard to keep things working. The cost in terms of disk size for the inverse relationships really is insignificant in comparison to the benefit it gains you.

Inverses are also used for Object Integrity (for other reasons, see the other answers):

The recommended approach is to model relationships in both directions and specify the inverse relationships appropriately. Core Data uses this information to ensure the consistency of the object graph if a change is made

From: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/HowManagedObjectsarerelated.html#//apple_ref/doc/uid/TP40001075-CH17-SW1

The provided link gives you ideas why you should have an inverse set. Without it, you can lose data/integrety. Also, the chance that you access an object which is nil is more likely.

There is no need for inverse relationship generally. But there are few quirks/bugs in Core data where you need an inverse relationship. There are cases where relationships/objects go missing , even though there is no error while saving the context, if there are missing inverse relationship. Check this example, which I created to demonstrate objects missing and how to workaround, while working with Core data

Related