I think we need a remedial coding forum...
Here's the whole implementation of the Controller:
#import "HikerController.h"
#import "Hike.h"
@implementation HikerController
-(int) numberOfRowsInTableView: (NSTableView *) theTableView {
return [hikeKeys count];
}
-(id) tableView: (NSTableView *) theTableView
objectValueForTableColumn: (NSTableColumn *) theColumn
row: (int) rowIndex
{
return [hikeKeys objectAtIndex:rowIndex];
}
- (void) awakeFromNib
{
[hikeTableView setDataSource:self];
[hikeTableView sizeLastColumnToFit];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textDidChange

name:NSControlTextDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textDidChange

name:NSTextDidChangeNotification object:notesField];
}
-(void) textDidChange

NSNotification *) notification
{
recordNeedsSaving=YES;
}
-(NSApplicationTerminateReply)applicationShouldTerm inate

id)sender
{
NSString *storePath=[NSHomeDirectory()
stringByAppendingPathComponent:@"Documents/HikerData.hik"];
[self addRecord:self];
if (hikeDict)
[NSArchiver archiveRootObject:hikeDict toFile:storePath];
return NSTerminateNow;
}
-(id) init
{
NSString *storePath=[NSHomeDirectory()
stringByAppendingPathComponent:@"Documents/HikerData.hik"];
[super init];
hikeDict=[NSUnarchiver unarchiveObjectWithFile:storePath];
if (!hikeDict) {
hikeDict=[[NSMutableDictionary alloc] init];
hikeKeys=[[NSMutableArray alloc] initWithCapacity:10];
} else {
hikeDict=[[NSMutableDictionary alloc]
initWithDictionary:hikeDict];
hikeKeys=[[NSMutableArray alloc]
initWithArray:[[hikeDict allKeys]
sortedArrayUsingSelector:
@selector (caseInsensitiveCompare

]];
}
recordNeedsSaving=NO;
return self;
}
-(void) dealloc
{
[hikeDict release];
[hikeKeys release];
[super dealloc];
}
- (IBAction)addRecord

id)sender
{
Hike *aHike;
NSString *hikeName=[hikeField stringValue];
if (recordNeedsSaving && ![hikeName isEqualToString:@""])
{
aHike=[hikeDict objectForKey:hikeName];
if (!aHike) {
aHike=[[[Hike alloc] init] autorelease];
[hikeKeys addObject:hikeName];
[hikeKeys sortUsingSelector:@selector(compare

];
[hikeTableView reloadData];
[hikeTableView selectRow:
[hikeKeys indexOfObject:hikeName]
byExtendingSelection:NO];
}
[self extractFields:aHike];
recordNeedsSaving=NO;
[hikeField selectText:self];
}
}
- (IBAction)blankFields

id)sender
{
[hikeField setStringValue:@""];
[trailheadField setStringValue:@""];
[exitField setStringValue:@""];
[notesField setString:@""];
[distanceField setFloatValue:0.0];
[hikeField selectText:self];
}
- (IBAction)deleteRecord

id)sender
{
NSString *hikeName = [hikeField stringValue];
[hikeDict removeObjectForKey:hikeName];
[hikeKeys removeObject:hikeName];
[hikeTableView reloadData];
[self blankFields:self];
}
- (IBAction)difficultyButtonClicked

id)sender
{
}
- (IBAction)handleTVClick

id)sender
{
Hike *aRec;
NSString *hikeName;
int index = [sender selectedRow];
if (index==-1) return;
hikeName=[hikeKeys objectAtIndex:index];
if (recordNeedsSaving) {
[self addRecord:self];
index=[hikeKeys indexOfObject:hikeName];
[hikeTableView selectRow:index byExtendingSelection:NO];
}
aRec=[hikeDict objectForKey:hikeName];
[self populateFields:aRec];
}
-(void) extractFields: (Hike *) aRec
{
[aRec setName:[hikeField stringValue]];
[aRec setTrailhead: [trailheadField stringValue]];
[aRec setExit: [exitField stringValue]];
[aRec setDistance: [distanceField floatValue]];
[aRec setNotes: [notesField string]];
[aRec setDifficulty: [difficultyButton indexOfSelectedItem]];
}
-(void) populateFields: (Hike *) aRec
{
[hikeField setStringValue: [aRec name]];
[exitField setStringValue: [aRec exit]];
[trailheadField setStringValue: [aRec trailhead]];
[distanceField setFloatValue: [aRec distance]];
[notesField setString: [aRec notes]];
[difficultyButton setState:1 atColumn:[aRec difficulty]-1];
[hikeField selectText:self];
}
@end