在自定义NSNotification
子类中添加或删除多对多关系/ NSSet
时,触发NSManagedObject
的正确方法是什么?
我有一个自定义NSManagedObject
子类,它与另一个NSManagedObject
子类具有一对多的无序关系。为清楚起见,我们假设这两个子类是Teacher
和Student
,其中一个Teacher
可以有多个Student
个对象,但每个Student
是仅分配给一个Teacher
。
我希望只要Student
添加到Teacher
或从Student
移除Teacher
,就会触发通知,无论是因为Student
只是分配给了NSSet
还是来自count
或者是因为@dynamic
完全从Core Data中删除了。
我尝试使用KVO,但似乎你可以将观察者添加到中添加一个观察者一个{{1}}财产。另外,我尝试实现我自己的自定义to-many访问器方法,如Apple's documentation中所述,但在测试中,似乎我的自定义访问器方法永远不会被调用。如果我的实现出现问题,请按照{{1}}: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}}
答案 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。