2015-03-31 52 views
2

無論何時在自定義NSManagedObject子類中將項目添加到對多關係/ NSSet或從其中刪除對象時,觸發NSNotification的正確方法是什麼?如何在項目添加到核心數據NSManagedObject關係的NSSet或從中刪除項目時觸發通知?

我有一個自定義的NSManagedObject子類,它與另一個NSManagedObject子類具有一對多的無序關係。爲了清楚起見,我們假設這兩個子類是TeacherStudent,其中一個Teacher可以有多個Student對象,但其中每個Student只分配給一個Teacher

我想能夠觸發每當Student被添加或刪除從Teacher的通知時,無論是因爲Student簡單地分配到或從一個或Teacher是否因爲Student從核心數據全部刪除。

我嘗試使用志願,但它似乎並不像你可以觀察者添加到NSSetcount財產觀察者添加到@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 
+0

我相信你只需要重寫'setStudents'和存取器,在使用'primitiveStudents'來調用'setPrimitiveStudents'來增加兩個集合。 您要重新實施的文檔不是「學生」資產的標準訪問者。將它們視爲便捷訪問器,就像指定方便的初始化工具一樣。您已確保它們符合KVO,但您並未確保其他代碼使用它們。此外,如果您想使用KVO,則必須KVO觀察'學生'鍵路徑,並且您可以在該代碼中同時獲得舊的和新的集合。 – stevesliva 2015-03-31 04:16:08

+0

如何覆蓋'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

+0

錯字。 「和」應該從該評論中省略。 '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

回答

3

的基本問題原來是,在Apple Docs看中訪問的例子,你是爲基準,實際上不是全部關係的訪問者。它們是您可以實現的額外便利訪問器。但是因爲你試圖通過覆蓋所有setter(或者你想調用的mutter訪問器)來插入你的代碼,你還需要覆蓋最基本的setter。

一對多關係的最基本訪問器是整個關係的NSSet對象的setter和getters。在你的情況下,- (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]; 

} 

是被默認使用的制定者。

相關問題