I've got a simple view controller with an NSMutableSet property called selectedEmails
. In viewDidLoad
I create the empty set and subscribe to changes:
self.selectedEmails = [NSMutableSet set];
[RACObserve(self, selectedEmails) subscribeNext:^(id emails) {
NSLog(@"set: %@", emails);
}];
For debugging purposes, I then add an item to the set in viewDidAppear:
. However, the subscription block only fires once, for the initial empty set, and never for the new, updated set.
Why is this? How can I fix it so I can observe the changes? I see in the answer to a different question that you can't observe a set but only the class that contains it – does that means that ReactiveCocoa won't work on sets?
I'd imagine you're not getting the notification since you're observing a pointer to selectedEmails, and as far as ReactiveCocoa is concerned, this value has not changed. The information contained at that location has changed (i.e. the object has been mutated), but the pointer itself is still referencing the same object.
There is no "plug and play" solution for what you're trying to do. In addition to the methods proposed in the answer you linked and the one in the comments above, you could also go with a more caveman-style approach where instead of using a mutable set, use a regular set and create a new object whenever you want to change the set.
Note that this is a cumbersome approach and is very prone to human error, so you should probably favour one of the other ones mentioned.
@property NSSet* selectedEmails;
// Create it
self.selectedEmails = [NSSet set];
// Add to it
self.selectedEmails = [self.selectedEmails setByAddingObject:someObject];
// Remove from it
NSMutableSet* mutableCopy = [self.selectedEmails mutableCopy]:
[mutableCopy removeObject:someObject];
self.selectedEmails = mutableCopy;