【发布时间】:2015-03-31 02:10:29
【问题描述】:
每当在自定义NSManagedObject 子类中向一对多关系/NSSet 添加或删除项目时,触发NSNotification 的正确方法是什么?
我有一个自定义的 NSManagedObject 子类,它与另一个 NSManagedObject 子类具有一对多的无序关系。为了清楚起见,假设这两个子类是Teacher 和Student,其中一个Teacher 可以有多个Student 对象,但每个Student 只分配给一个Teacher。
我希望能够在 Student 添加到 Teacher 或从 Teacher 删除时触发通知,无论是因为 Student 只是简单地分配给 Teacher 或从 Teacher 分配,还是因为 @987654338 @ 已从 Core Data 中完全删除。
我尝试使用 KVO,但您似乎无法将观察者添加到 将观察者添加到 NSSet 的 count 属性@dynamic 属性。此外,我尝试按照Apple's documentation 中的说明实现我自己的自定义多对多访问器方法,但在测试中似乎从未调用过我的自定义访问器方法。如果我的实现有问题,下面是我在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
【问题讨论】:
-
我相信您只需要覆盖
setStudents和访问器,在使用primitiveStudents后调用setPrimitiveStudents来对两组进行增量。您重新实现的文档不是students属性的标准访问器。以指定和便利初始化器的方式将它们视为便利访问器。您已确保它们与 KVO 兼容,但您尚未确保其他代码使用它们。另外,如果你想使用 KVO,你必须 KVO 观察students键路径,你可以在该代码中获取旧集和新集。 -
如何覆盖
setStudents及其访问器?我在developer.apple.com/library/mac/documentation/Cocoa/Conceptual/… 中看到了“自定义原始访问器方法”部分,但不知道如何实现它,因为我不知道您在哪里定义了nonCompliantKVCivar。 -
错字。该注释中应省略“和”。
setStudents是学生属性的设置器访问器。-(void) setStudents:(NSSet*)students{ [self willChangeValueForKey:@"students"]; [self setPrimitiveValue:students forKey:@"students"]; [self didChangeValueForKey:@"students"]; }尝试在其中插入您的通知。或者,就像我说的,在students键路径上使用 KVO。无论如何,您实现的访问器不会被任何标准控制器使用。第三个选项是 MOC 的更改通知。 -
谢谢!您可以将此添加为答案吗?
标签: ios objective-c core-data nsmanagedobject nsset