Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutable sets in NSManagedObjects?

The standard declaration for an autogenerated NSManagedObject property declares to-many relationships like this:

@property (nonatomic, retain) NSSet *somethings;
...
@dynamic somethings;

Would it be safe to change that declaration to an NSMutableSet? Would the CoreData component still function correctly?

Judging by the @dynamic, it probaby doesn't care if I use an NSSet subclass rather than an NSSet, but I don't want to rewrite a lot of code only to find out it doesn't work.

like image 415
Greg Avatar asked Mar 12 '12 05:03

Greg


2 Answers

According to Apple's Core Data Programming Guide, this should always be declared as a NSSet.

If you want a mutable proxy (which is basically the mutable version of the core data set and works exactly the same) then you would use the function mutableSetValueForKey like this:

// myManagedObject is the managed object that has the somethings property.
NSMutableSet *mutableSomethings = [myManagedObject mutableSetValueForKey:@"somethings"];

mutableSomethings can then be modified as a standard NSMutableSet andsomethings will be updated and KVO methods will be appropriately called.

Note however, that many features of the mutable set (such as addSomethingsObject and removeSomethingsObject) are already provided in the core data generated accessors so in many cases you don't need to use the proxy.

like image 151
lnafziger Avatar answered Sep 28 '22 19:09

lnafziger


You should keep it as an NSSet and do one of the following:

  1. Use key value coding
  2. Add the core data generated accessors

For key value coding, you'll access your collection like so:

NSMutableSet *somethings = [object mutableSetValueForKey:@"somethings"];
[somethings addObject:newObject];

For core data generated accessors, you'd add the following to your header:

@interface MyManagedObject (CoreDataGenerated)
- (void)addSomethingsObject:(MySomething *)object;
- (void)removeSomethingsObject:(MySomething *)object;
- (void)addSomethings:(NSSet *)somethings;
- (void)removeSomethings:(NSSet *)somethings;
@end

You do not need to implement these methods (Core Data will take care of it for you), and you can call them easily. This is my preferred way of handling collections because you get better type checking from the compiler.

The reason you should not change it to an NSMutableSet is because there is a good chance that you will cause crashes and/or that your changes will not be persisted into your Core Data store.

You may also want to look into mogenerator to help you out with creating all of your Cocoa classes.

like image 27
wbyoung Avatar answered Sep 28 '22 20:09

wbyoung