繁体   English   中英

当项目添加到核心数据NSManagedObject关系的NSSet中或从中删除时,如何触发通知?

[英]How to trigger notifications when item added to or removed from Core Data NSManagedObject relationship's NSSet?

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

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

我希望每当将Student添加到Teacher或从中删除Student都可以触发通知,无论是因为仅将Student分配给Teacher还是从Teacher分配Student ,或者是因为从核心数据中完全删除了Student

我尝试使用KVO,但似乎无法 NSSetcount属性添加观察者 将观察者添加到@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM