Online Book Reader

Home Category

Cocoa Programming for Mac OS X - Aaron Hillegass [51]

By Root 920 0
RMDocument.h, add:

#import

@class Person;

Now declare the methods in RMDocument.h:

- (void)insertObject:(Person *)p inEmployeesAtIndex:(NSUInteger)index;

- (void)removeObjectFromEmployeesAtIndex:(NSUInteger)index;

As we will be referencing the Person class in the methods we add to RMDocument.m, import Person’s header file near the top:

#import "RMDocument.h"

#import "Person.h"

Now add the method implementations to RMDocument.m:

- (void)insertObject:(Person *)p inEmployeesAtIndex:(NSUInteger)index

{

NSLog(@"adding %@ to %@", p, employees);

// Add the inverse of this operation to the undo stack

NSUndoManager *undo = [self undoManager];

[[undo prepareWithInvocationTarget:self]

removeObjectFromEmployeesAtIndex:index];

if (![undo isUndoing]) {

[undo setActionName:@"Add Person"];

}

// Add the Person to the array

[employees insertObject:p atIndex:index];

}

- (void)removeObjectFromEmployeesAtIndex:(NSUInteger)index

{

Person *p = [employees objectAtIndex:index];

NSLog(@"removing %@ from %@", p, employees);

// Add the inverse of this operation to the undo stack

NSUndoManager *undo = [self undoManager];

[[undo prepareWithInvocationTarget:self] insertObject:p

inEmployeesAtIndex:index];

if (![undo isUndoing]) {

[undo setActionName:@"Remove Person"];

}

[employees removeObjectAtIndex:index];

}

These methods will be called automatically when the NSArrayController wishes to insert or remove Person objects (for example, when the Add Employee and Remove buttons send it insert: and remove: messages).

At this point, you have made it possible to undo deletions and insertions. Undoing edits will be a little trickier. Before tackling this task, build and run your application. Test the undo capabilities that you have at this point. Note that redo also works.

Key-Value Observing


In Chapter 7, we discussed key-value coding. To review, key-value coding is a way to read and change a value by name. Key-value observing allows you to be informed when these sorts of changes occur.

To enable undo capabilities for edits, you will want your document object to be informed of changes to the keys expectedRaise and personName for all its Person objects.

A method in NSObject allows you to register to be informed of these changes:

- (void)addObserver:(NSObject *)observer

forKeyPath:(NSString *)keyPath

options:(NSKeyValueObservingOptions)options

context:(void *)context;

You supply the object that should be informed as observer and the keyPath for which you wish to be informed about changes. The options variable defines what you would like to have included when you are informed about the changes. For example, you can be told about the old value (before the change) and the new value (after the change). The context variable is a pointer to data that you would like sent with the rest of the information.

When a change occurs, the observer is sent the following message:

- (void)observeValueForKeyPath:(NSString *)keyPath

ofObject:(id)object

change:(NSDictionary *)change

context:(void *)context;

The observer is told which key path changed in which object. Here, change is a dictionary that (depending on the options you asked for when you registered as an observer) may contain the old value and/or the new value. Of course, this method is sent the context pointer supplied when the method was registered as an observer.

Using the Context Pointer Defensively

Because any object observing key-value changes must implement a method with this specific selector (observeValueForKeyPath:ofObject:change:context:), it is possible to mistakenly intercept notifications intended for another class.

Consider the case of a fictional class Maple, which is a subclass of a fictional class Tree. Both classes observe the key path season independently. Unless the developer takes precautions, Maple will receive its key-value-observing (KVO) messages and those intended for Tree, because Maple has effectively overridden the KVO method. To fix this, Maple must correctly

Return Main Page Previous Page Next Page

®Online Book Reader