[英]How to trigger notifications when item added to or removed from Core Data NSManagedObject relationship's NSSet?
每当将项目添加到自定义NSManagedObject
子类中的多对多关系/ NSSet
或从中删除项时,触发NSNotification
的正确方法是什么?
我有一个自定义NSManagedObject
子类,该子类与另一个NSManagedObject
子类具有一对多的无序关系。 为了清楚起见,假设这两个子类是Teacher
和Student
,其中一个Teacher
可以具有多个Student
对象,但是每个Student
只分配给一个Teacher
。
我希望每当将Student
添加到Teacher
或从中删除Student
都可以触发通知,无论是因为仅将Student
分配给Teacher
还是从Teacher
分配Student
,或者是因为从核心数据中完全删除了Student
。
我尝试使用KVO,但似乎无法 向 将观察者添加到NSSet
的count
属性添加观察者 @dynamic
属性。 此外,我尝试实现苹果文档中概述的自己的自定义“一对多”访问器方法,但在测试中似乎从未调用过我的自定义访问器方法。 如果我的实现出现问题,这是我在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
根本的问题是,您用作参考的Apple Docs中精美的访问器示例实际上并不是该关系的所有访问器。 它们是您可以实现的额外的便捷访问器。 但是,因为您试图通过覆盖所有设置器(或任何您想要调用变异访问器的方法)来插入代码,所以您还需要覆盖最基本的设置器。
一对多关系的最基本访问器是整个关系的NSSet
对象的设置器和获取器。 在您的情况下, - (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。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.