Database Reference
In-Depth Information
Accessing a To-Many Relationship
The many side of a relationship is stored unordered. This means each time
we fetch the objects on the many side of a relationship, the order is not
guaranteed, and it is probable that the order will change between fetches.
However, we are guaranteed that each object will be included only once. In
other words, when we access a to-many relationship using
KVC
, we will get
an
NSSet
back. For example, if we want to access the ingredients of a recipe,
we would use code similar to the following:
NSManagedObject *recipe = ...;
NSSet *ingredients = [recipe valueForKey:@
"ingredients"
];
Likewise, setting the ingredients into a recipe is as follows:
NSManagedObject *recipe = ...;
NSSet *someIngredients = ...;
[recipe setValue:someIngredients forKey:@
"ingredients"
];
Mutable Access of To-Many Relationships
You might notice that the
NSSet
we get back when accessing a to-many rela-
tionship is immutable. Adding an object to a to-many relationship with an
immutable
NSSet
requires creating a mutable copy of the
NSSet
, adding the new
object to the
NSMutableSet
, and setting the
NSMutableSet
back onto the parent
object. It's a painful process and, fortunately, unnecessary. When we want
to add an object to a to-many relationship, we can use
-mutableSetValueForKey:
in the place of
-valueForKey:
. This returns an
NSMutableSet
for us that is already
associated with the parent object and reduces our code to the following:
NSManagedObject *newIngredient = ...;
NSManagedObject *recipe = ...;
NSMutableSet *ingredients = [recipe mutableSetValueForKey:@
"ingredients"
];
[ingredients addObject:newIngredient];
Note that we did not need to set the
NSMutableSet
back into the entity, and
therefore the code to add an object to a to-many relationship is quite short.
One important thing to notice in these relationship examples is that when
we update the relationship, we are updating only one side of it. Because we
defined these relationships as double-sided (that is, they include an inverse
relationship that we defined in
Section 1.1,
NSManagedObjectModel
, on page
1
), Core Data handles keeping the integrity of the relationships intact. When
we update one side of a relationship, Core Data automatically goes in and
sets the other side for us.