Online Book Reader

Home Category

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

By Root 886 0
give users the ability to undo the effects of clicking the Add New Employee and Delete buttons, as well as the ability to undo the changes they make to Person objects in the table. The necessary code will go into your RMDocument class.

Key-Value Coding and To-Many Relationships


When designing a class, think of your instance variables as having one of four possible purposes:

1. Simple attributes. Example: Each student has a first name. Simple attributes are typically numbers or instances of NSString, NSDate, or NSData.

2. To-one relationships. Example: Each student has a school. It is like a simple attribute, but the type is a complex object, not a simple one. To-one relationships are implemented using pointers: An instance of Student has a pointer to an instance of School.

3. Ordered to-many relationships. Example: Each playlist has a list of songs. The songs are in a particular order. This is typically implemented using an NSMutableArray.

4. Unordered to-many relationships. Example: Each department has a bunch of employees. You can display the employees in a particular order (such as sorted by last name), but that ordering is not inherent in the relationship. This is typically implemented using an NSMutableSet.

Earlier, we discussed how we could set simple attributes and to-one relationships using key-value coding. Remember that when setting or getting a value for fido, KVC will use the accessors if they exist. Similarly, we can create accessors for ordered and unordered to-many relationships.

Let’s say, for example, that an instance of Playlist has an NSMutableArray of Song objects. If you want to use key-value coding to manipulate that array you will ask the playlist for its mutableArrayValueForKey:. You will get back a proxy object.

That proxy object knows that it represents the array that holds the songs.

id arrayProxy = [playlist mutableArrayValueForKey:@"songs"];

int songCount = [arrayProxy count];

In this example, when asked for the count, the proxy object will ask the Playlist object if it has a countOfSongs method. If Playlist does, it will call the method and return the result. If there is no such method, Playlist will get the array of songs and ask the array for its count (Figure 9.3). Note, then, that naming the method countOfSongs is not just a convention; rather, the key-value coding mechanism goes looking for a method with the right name.

Figure 9.3. Key-Value Coding for Ordered Relationships

There are several cases, so here is a list:

id arrayProxy = [playlist mutableArrayValueForKey:@"songs"];

int x = [arrayProxy count]; // is the same as

int x = [playlist countOfSongs]; // if countOfSongs exists

id y = [arrayProxy objectAtIndex:5] // is the same as

id y = [playlist objectInSongsAtIndex:5]; // if the method exists

[arrayProxy insertObject:p atIndex:4] // is the same as

[playlist insertObject:p inSongsAtIndex:4]; // if the method exists

[arrayProxy removeObjectAtIndex:3] // is the same as

[playlist removeObjectFromSongsAtIndex:3] // if the method exists

There is a similar set of calls for unordered to-many relationships (Figure 9.4).

Figure 9.4. Key-Value Coding for Unordered Relationships

id setProxy = [teacher mutableSetValueForKey:@`students"];

int x = [setProxy count]; // is the same as

int x = [teacher countOfStudents]; // if countOfStudents exists

[setProxy addObject:newStudent]; // is the same as

[teacher addStudentsObject:newStudent]; // if the method exists

[setProxy removeObject:expelledStudent]; // is the same as

[teacher removeStudentsObject:expelledStudent]; // if the method exists

Because we have bound the contentArray of the array controller to the employees array of the RMDocument object, the array controller will use key-value coding to add and remove Person objects. You will take advantage of this to add undo invocations to the undo stack when people are added and removed.

Before we declare these methods in the header file, we must tell the compiler that the Person class exists. In

Return Main Page Previous Page Next Page

®Online Book Reader