如何在Core Data NSManagedObject关系的NSSet中添加或删除项时触发通知?

时间:2015-03-31 02:10:29

标签: ios objective-c core-data nsmanagedobject nsset

在自定义NSNotification子类中添加或删除多对多关系/ NSSet时,触发NSManagedObject的正确方法是什么?

我有一个自定义NSManagedObject子类,它与另一个NSManagedObject子类具有一对多的无序关系。为清楚起见,我们假设这两个子类是TeacherStudent,其中一个Teacher可以有多个Student个对象,但每个Student是仅分配给一个Teacher

我希望只要Student添加到Teacher或从Student移除Teacher,就会触发通知,无论是因为Student只是分配给了NSSet还是来自count或者是因为@dynamic完全从Core Data中删除了。

我尝试使用KVO,但似乎你可以将观察者添加到Teacher @implementation Teacher @dynamic students; - (void)addStudentsObject:(Student *)value { NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; [self willChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [[self primitiveStudents] addObject:value]; [self didChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects]; [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_TEACHER_STUDENT_WAS_ADDED object:self]; } - (void)removeStudentsObject:(Student *)value { NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1]; [self willChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; [[self primitiveStudents] removeObject:value]; [self didChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects]; [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_TEACHER_STUDENT_WAS_REMOVED object:self]; } - (void)addStudents:(NSSet *)values { [self willChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueUnionSetMutation usingObjects:values]; [[self primitiveStudents] unionSet:values]; [self didChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueUnionSetMutation usingObjects:values]; [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_TEACHER_STUDENTS_WERE_ADDED object:self]; } - (void)removeStudents:(NSSet *)values { [self willChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueMinusSetMutation usingObjects:values]; [[self primitiveStudents] minusSet:values]; [self didChangeValueForKey:NSStringFromSelector(@selector(students)) withSetMutation:NSKeyValueMinusSetMutation usingObjects:values]; [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_TEACHER_STUDENTS_WERE_REMOVED object:self]; } ... @end 属性中添加一个观察者一个{{1}}财产。另外,我尝试实现我自己的自定义to-many访问器方法,如Apple's documentation中所述,但在测试中,似乎我的自定义访问器方法永远不会被调用。如果我的实现出现问题,请按照{{1}}:

的方式实现
{{1}}

1 个答案:

答案 0 :(得分:3)

基本问题证明,您作为参考使用的Apple Docs中的精美访问者示例实际上并非所有关系的访问者。如果您愿意,它们是您可以实现的额外便利访问器。但是因为你试图通过覆盖所有的setter(或者你想要调用mutating访问器的任何东西)来插入你的代码,你还需要覆盖最基本的setter。

for-many关系的最基本访问器是整个关系的NSSet对象的setter和getter。在您的情况下,- (NSSet*) students- (void) setStudents:(NSSet*)students

因此,您的通知至少需要在setStudents

中发布
-(void) setStudents:(NSSet*)students{ 
    [self willChangeValueForKey:@"students"]; 
    [self setPrimitiveValue:students forKey:@"students"]; 
    [self didChangeValueForKey:@"students"]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_TEACHER_STUDENTS_WERE_ADDED object:self];

} 

是默认使用的setter。