Search code examples
iosobjective-ckey-value-observing

Can KVO be used to deeply observe variable collections?


I get how to use K-V-O for simple property stuff. I have a model that looks like

@interface WateringScript : NSObject
@property (strong, nonatomic) NSMutableArray* spans; // holds WateringSpans
...
@end

@interface WateringSpan : NSObject
@property (strong, nonatomic) WateringAnchor* begin;
@property (strong, nonatomic) WateringAnchor* end;
...
@end

@interface WateringAnchor : NSObject
@property (assign, nonatomic) NSTimeInterval offset;
...
@end

Basically a top level object that holds a series of spans, the spans being defined as end and begin anchor objects, which amongst other things have an offset.

I have a custom view that would like to draw all of the offsets. Is there a simple way to observe all of the offsets? Such that as they change, or spans or added or removed, I can be notified of it and react accordingly?

Or do I have to observe the collection, and then on initial/add/remove changes observe and unobserve the collection elements? I think I could code this up if I have to, the real question is there KVO Juju that makes it easier?


Solution

  • You can't key-value observe through arrays. You have to observe the to-many property (spans) for changes to its content and separately observe the elements.

    Once you handle addition and removal of elements so that you start and stop observing their properties, you can leverage that for the initial setup by specifying NSKeyValueObservingOptionInitial when you start observing the to-many property itself. You'll essentially be told that the initial elements have been "added".

    For actually handling the added and removed elements, you can use -[NSArray addObserver:toObjectsAtIndexes:forKeyPath:options:context:] and -removeObserver:fromObjectsAtIndexes:forKeyPath: to start and stop observing their properties en masse.

    It ends up being not too much code.