無論何時在自定義NSManagedObject
子類中將項目添加到對多關係/ NSSet
或從其中刪除對象時,觸發NSNotification
的正確方法是什麼?如何在項目添加到核心數據NSManagedObject關係的NSSet或從中刪除項目時觸發通知?
我有一個自定義的NSManagedObject
子類,它與另一個NSManagedObject
子類具有一對多的無序關係。爲了清楚起見,我們假設這兩個子類是Teacher
和Student
,其中一個Teacher
可以有多個Student
對象,但其中每個Student
只分配給一個Teacher
。
我想能夠觸發每當Student
被添加或刪除從Teacher
的通知時,無論是因爲Student
簡單地分配到或從一個或Teacher
是否因爲Student
從核心數據全部刪除。
我嘗試使用志願,但它似乎並不像你可以觀察者添加到觀察者添加到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'來增加兩個集合。 您要重新實施的文檔不是「學生」資產的標準訪問者。將它們視爲便捷訪問器,就像指定方便的初始化工具一樣。您已確保它們符合KVO,但您並未確保其他代碼使用它們。此外,如果您想使用KVO,則必須KVO觀察'學生'鍵路徑,並且您可以在該代碼中同時獲得舊的和新的集合。 – stevesliva 2015-03-31 04:16:08
如何覆蓋'setStudents'及其訪問器?我在https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdAccessorMethods.html中看到了「Custom Primitive Accessor Methods」部分,但無法弄清楚如何執行它,因爲我沒有'不知道你在哪裏定義'nonCompliantKVCivar'。 – 2015-03-31 21:39:05
錯字。 「和」應該從該評論中省略。 'setStudents'是學生財產的設置器訪問器。' - (void)setStudents:(NSSet *)students {[self willChangeValueForKey:@「students」]; [self setPrimitiveValue:students forKey:@「students」]; [self didChangeValueForKey:@「students」]; }嘗試在那裏插入你的通知。或者,就像我所說的,在學生的關鍵路徑上使用KVO。在任何情況下,您實施的訪問器都不會被任何標準控制器使用。第三個選項是MOC的更改通知。 – stevesliva 2015-04-01 03:00:28