views:

96

answers:

2

I have a question regarding using KVO-compliant methods to insert/remove objects from an array. I'm working through Aaron Hillegass' Cocoa Programming for Mac OS X and I saw the following line of code (in the insertObject:inEmployeesAtIndex: method:

[[undoManager prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];

Correct me if I'm wrong, but I always thought it was better to call mutableArrayValueForKey: and then removeObjectAtIndex:...so I tried changing the above line to this:

[[undoManager prepareWithInvocationTarget:[self mutableArrayValueForKey:@"employees"]] removeObjectAtIndex:index]; 

And it didn't work. Can someone explain the difference and why the first line works but the second line doesn't?

UPDATE: My removeObjectFromEmployeesAtIndex:index method is implemented to make my collection class (an instance of NSMutableArray) KVC-compliant. So ultimately, calling [[self mutableArrayValueForKey:@"employees"] removeObjectAtIndex:index]; should end up calling [self removeObjectFromEmployeesAtIndex:index];

A: 

Yes. The first line (from the book) is basically equivalent to this:

id tmp = [undoManager prepareWithInvocationTarget:self];
[tmp removeObejctFromEmployeesAtIndex:index];

Your code, however, is basically equivalent to this:

id tmp1 = [self mutableArrayValueForKey:@"employees"];
id tmp2 = [undoManager prepareWithInvocationTarget:tmp1];
[tmp2 removeObjectAtIndex:index];

In other words, the target that you're preparing the invocation with is different in your code (unless self happens to be the same object as [self mutableArrayValueForKey:@"employees"], which is doubtful).

mipadi
Oh, sorry for the confusion. I updated the post with some more detail. But actually, I do want to call -removeObjecAtIndex: on [self mutableArrayValueForKey:@employees"]
jasonbogd
+1  A: 

In your update you say:

calling [[self mutableArrayValueForKey:@"employees"] removeObjectAtIndex:index]; should end up calling [self removeObjectFromEmployeesAtIndex:index];

Unfortunately this is not correct not matter what is in your removeObjectFromEmployeesAtIndex: method as NSMutableArray will never call any methods in your class. Since you seem to be trying to get undo/redo functionality you have to use a method like removeObjectFromEmployeesAtIndex:. Otherwise when you hit undo for adding an employee you will have no way to 'redo' adding that employee. You also could have issues with undo/redo for edits to individual employees. If you wanted to you could change the line in the removeObjectFromEmployeesAtIndex: method that reads [employees removeObjectAtIndex:index]; to [[self valueForKey:@"employees"] removeObjectAtIndex:index]; or [self.employees removeObjectAtIndex:index]; but there is really no reason to go this route.

theMikeSwan