Another way to add object to immutable collection
onmyway133 opened this issue · 1 comments
Hi, with KVC, we have another option mutableArrayValueForKey, mutableSetValueForKey to add object to the immutable collection
Extract from the Core Data 2nd book, section 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
What do you think?
Say you have a class like this
@interface User
@property (nonatomic, strong) NSArray *books;
@end
How do you add an object to books
?
Probably I might not getting right the question but I will probably not have a class like the one you described.
I will rather do something like this:
@interface User
@property (nonatomic, readonly) NSArray *books;
- (void)addBook:(Book *)book
@end
@implementation User ()
@property (nonatomic, strong) NSMutableArray *mutableBooks;
@end
@implementation User
- (void)addBook:(Book *)book
{
[self.mutableBooks addObject:book];
}
- (NSArray *)books
{
return [self.mutableBooks copy];
}
@end
If you need or want to got for the extra mile inside addBook:
you can implement thread safety logic to access the mutable array from different thread.
Exposing the array interface breaks the encapsulation and let the user of the class to fiddle with you internal representation that can eventually change in the future.