I am maintaining an array of 'Category' objects which are simply descriptive NSStrings. These categories are assigned to Job objects from an arraycontroller bound to the category array. The list of categories is editable by the user so that categories can be added, deleted or renamed. The Job objects have a reference to the chosen category for that job. Therefore, a category can be assigned to each job object by selecting from a popup list composed of the arrangedObjects of the category array.
Everything works okay until a category is deleted. Job objects that referred to the deleted category continue to maintain a reference to it. In the GUI, the category is displayed as an address: "<Category: 0x495680>". I assume this is the stale reference to the category that is now gone.
How can I assure that if a category is deleted, any job objects that have a reference to it are changed to nil?
I've been looking at the KVO and KVC sections of documentation, but haven't been able to get to where I need to go. Both the array of jobs and the array of categories are being maintained by my AppController object. The job objects are in a higher-level array which can contain any number of jobs:
@interface AppController : NSObject {
NSMutableArray *routes; // array of routelists
NSMutableArray *emps; // array of employees
NSMutableArray *categories; // category list. bound from GUI via catController
[...]
}
@interface RouteList : NSObject <NSCoding> {
NSMutableDictionary *properties;
NSMutableArray *jobs; // Job objects for this particular route
}
@interface Job : NSObject <NSCoding> {
NSMutableDictionary *properties; // properties.category is reference from category array
}
Since my controller owns both, I figure that's where I need to watch for changes. To this end, I've added addObserver: to AppController so as to receive NSKeyValueChangeRemoval notifications for the categories keypath (which seems a little strange).
from AppController:
- (void)awakeFromNib {
[ ... ]
// add self as observer to our own categories array?
[self addObserver:self
forKeyPath:@"categories"
options:( NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew )
context:NULL];
[ ... ]
}
Where I can't make the next connection is how to go about looking through the Job objects in the array to check if they have the same reference. My plan would be to step through those that do and set their category property to nil. Although it seems there should be a better way to do that. Every time I delete a category I now receive two(?) notifications. I think that what is passed in NSKeyValueChangeOldKey is the old address the deleted object? Not sure though:
- (void)observeValueForKeyPath: (NSString *)path
ofObject: (id)object
change: (NSDictionary *)change
context: (void *)context
{
if( [[change valueForKey:NSKeyValueChangeKindKey] intValue] == NSKeyValueChangeRemoval ) {
// here we have a removal event from the categories array. get an array of the jobs in
// our routelists that have the same address and set them to nil?
}
}
Am I on the right path with this methodology? Thanks in advance.
#mikec