Reputation: 9923
Not sure what I'm doing wrong here.
School has a to-many to Student, and Student has its inverse.
A little test code as follows:
@class Student;
@interface School : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSOrderedSet *students;
@end
@interface School (CoreDataGeneratedAccessors)
- (void)insertObject:(Student *)value inStudentsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromStudentsAtIndex:(NSUInteger)idx;
- (void)insertStudents:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeStudentsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInStudentsAtIndex:(NSUInteger)idx withObject:(Student *)value;
- (void)replaceStudentsAtIndexes:(NSIndexSet *)indexes withStudents:(NSArray *)values;
- (void)addStudentsObject:(Student *)value;
- (void)removeStudentsObject:(Student *)value;
- (void)addStudents:(NSOrderedSet *)values;
- (void)removeStudents:(NSOrderedSet *)values;
@end
// Meanwhile, elsewhere...
-(void)go {
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [app managedObjectContext];
School *school = (School *)[NSEntityDescription insertNewObjectForEntityForName:@"School" inManagedObjectContext:context];
[school setName:@"Stanford"];
Student *student = (Student *)[NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:context];
[student setName:@"Eric"];
//[school addStudentsObject:student];
NSMutableSet *students = [school mutableSetValueForKey:@"students"];
[students addObject:student];
NSError *__autoreleasing error;
BOOL success = [context save:&error];
if (!success) {
@throw [NSException exceptionWithName:NSGenericException
reason:[error description]
userInfo:nil];
}
}
Using the commented addStudentsObject:
fails with:
2013-04-13 16:22:58.648 CDTMTest[2098:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSSet intersectsSet:]: set argument is not an NSSet'
*** First throw call stack:
(0x1fa2012 0x13dfe7e 0x2030a4a 0xb85ec6 0xb087f9 0xb85d33 0x11aa638 0x7ee2069 0x2b4d 0xacd5b3 0x1f61376 0x1f60e06 0x1f48a82 0x1f47f44 0x1f47e1b 0x1efc7e3 0x1efc668 0x13ffc 0x1bdd 0x1b05)
libc++abi.dylib: terminate called throwing an exception
Using mutableSetValueForKey:
fails with
2013-04-13 16:07:05.111 CDTMTest[2012:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSManagedObjects of entity 'School' do not support -mutableSetValueForKey: for the property 'students''
*** First throw call stack:
(0x1fa3012 0x13e0e7e 0x11370da 0x3af3 0xace5b3 0x1f62376 0x1f61e06 0x1f49a82 0x1f48f44 0x1f48e1b 0x1efd7e3 0x1efd668 0x14ffc 0x2b7d 0x2aa5)
libc++abi.dylib: terminate called throwing an exception
Upvotes: 6
Views: 5217
Reputation: 6011
You might want to try this for adding to a set:
mutableOrderedSetValueForKey:
As you chose you to-many relationship to be ordered.
but i believe that it will be easier for you to just set the relationship the other way:
student.school = school;
Upvotes: 8
Reputation: 1876
I had a similar problem. I read somewhere that the basic core data implementation for to-many relationships doesn't work correctly all the time. It has something to do with the relationship only accepting an nsset and the generated setters not properly converting the incoming arguments to an nsset. To fix it try overriding the addStudentsObject: method with something like this:
static NSString *const kItemsKey = @"students";
- (void)addStudentsObject:(Student *)value {
NSMutableSet* tempSet = [NSMutableSet setWithSet:self.students];
NSSet* newObject = [NSSet setWithObject:value];
[self willChangeValueForKey:kItemsKey withSetMutation:NSKeyValueUnionSetMutation usingObjects:newObject];
[tempSet addObject:value];
self.students = tempSet;
[self didChangeValueForKey:kItemsKey withSetMutation:NSKeyValueUnionSetMutation usingObjects:newObject];
}
Upvotes: 2