Search code examples
iphonecocoa-touchkey-value-observing

When manually triggering a KVO event, can the change dictionary be amended?


I have a data model, composed mostly of an NSMutableArray 'contents' and NSMutableDictionary 'contentsByName'. I have ViewController objects that I wish to observe changes in the data model.

I have a property "count" on the model that returns the size of the array 'contents' and I can trigger a KVO change observation with willChange: and didChange:. So far, so good. However, the view-controllers are now aware that the model has changed, but do not know what's been added to it. Ideally, I need to put extra information into the change dictionary that's delivered to the observer.

Is this at all possible?


Solution

  • This is easily solvable by updating the model objects in a more granular way; however, built-in collections don't generate KVO notifications when their contents are modified, and will require some manual support.

    If you want to generate notifications about changes to the array, use willChange:valuesAtIndexes:forKey: and didChange:valuesAtIndexes:forKey: whenever it's modified. When these methods are used, the change dictionary will contain an entry for NSKeyValueChangeIndexesKey, which reflects the indexes of insertion, deletion, or replacement.

    If you want to generate notifications about changes to the dictionary, you can call willChangeValueForKey: and didChangeValueForKey: on the dictionary itself, like so:

    - (void)addContent:(id)content {
        NSString *key = [content name];
    
        [self.contentsByName willChangeValueForKey:key];
        [self.contentsByName setValue:content forKey:key];
        [self.contentsByName didChangeValueForKey:key];
    }
    

    Any observer can also use NSKeyValueObservingOptionNew or NSKeyValueObservingOptionOld to receive the new or old values, respectively.