title: How to trigger notifications when item added to or removed from Core Data NSManagedObject relationship's NSSet?
body: <p>What is the correct way to trigger an <code>NSNotification</code> whenever an item is added to or removed from a to-many relationship / <code>NSSet</code> within a custom <code>NSManagedObject</code> subclass?</p>
  
  <p>I have a custom <code>NSManagedObject</code> subclass that has a one-to-many unordered relationship to another <code>NSManagedObject</code> subclass. For clarity, let's say these two subclasses are <code>Teacher</code> and <code>Student</code>, where one <code>Teacher</code> can have multiple <code>Student</code> objects but where each <code>Student</code> is only assigned to one <code>Teacher</code>.</p>
  
  <p>I'd like to be able to trigger a notification whenever a <code>Student</code> is added to or removed from a <code>Teacher</code>, whether because <code>Student</code> was simply assigned to or from a <code>Teacher</code> or whether because <code>Student</code> was deleted entirely from Core Data.</p>
  
  <p>I tried using KVO but it doesn't seem like you can <del>add an observer to an <code>NSSet</code>'s <code>count</code> property</del> add an observer to a <code>@dynamic</code> property. Additionally, I tried implementing my own custom to-many accessor method as outlined in <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdAccessorMethods.html" rel="nofollow">Apple's documentation</a>, but in testing it seems like my custom accessor methods are never called. In case there is something wrong with my implementation, here is how I implemented it within <code>Teacher</code>:</p>
  
  <pre><code>@implementation Teacher
  
  @dynamic students;
  
  - (void)addStudentsObject:(Student *)value
  {
      NSSet *changedObjects = [[NSSet alloc] initWithObjects:&amp;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:&amp;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
  </code></pre>