Cocoa Programming for Mac OS X (Ch 9-12)

Read part one here, part two here and get the book here .

The plot thickens!

Chapter 9, NSUndoManager.

For those wondering what that NS is doing everywhere, it comes from NeXTSTEP more information about it here.

This chapter is all about adding undo / redo capabilities to your application and maybe it’s because the current sample application is, well, a sample, but it’s rather easy to add this capabilities to your program. Also you get it integrated with the menu bar at no extra cost, the window shows that there are changes, and the undo and redo buttons come to live. The underlying mechanism relies heavy upon Key-Value coding which was discussed in chapter 7 , again demonstrating it power.

- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index
{
    NSLog(@"adding %@ to %@", p, employees);
    NSUndoManager *undo = [self undoManager];
    [[undo prepareWithInvocationTarget:self] removeObjectFromEmployeesAtIndex:index];
    if(![undo isUndoing])
    {
        [undo setActionName:@"Insert Person"];
    }
    [self startObservingPerson:p];
    [employees insertObject:p atIndex:index];    
}

Chapter 10, Archiving.

The sample application now tracks changes and when you try to close an edited window it asks if it should save its changes. So the logical next chapter is about adding this capability.

In this chapter we learn that the notion of an interface in .Net actually also exists in Objective-C, but it’s called a protocol and unlike .Net and Java you can have optional methods in a protocol so any method marked optional does not need to be implemented.

Archiving is coupled with the NSCoding protocol and the abstract NSCoder class, most of the time you’ll be dealing with the abstracted class which hides the underlying mechanism. Implementing this can be compared to the implementation in .Net. Though it requires less code to write since your object graph is stored automatically in a file. You can configure the extension and the icon from within XCode, it was also nice to see that OS X had automatically associated the extension with my application.

#import <Foundation/Foundation.h>
 
@interface Person : NSObject <NSCoding>{
    NSString *personName;
    float expectedRaise;
}
 
@property (readwrite,copy) NSString *personName;
@property (readwrite) float expectedRaise;
 
@end
 
#import "Person.h"
 
@implementation Person
 
-(id)init
{
    [super init];
    expectedRaise = 5.0;
    personName = @"New Person";
    return self;
}
 
-(void)dealloc
{
    [personName release];
    [super dealloc];
}
 
@synthesize personName;
@synthesize expectedRaise;
 
- (void)setNilValueForKey:(NSString *)key
{
    if([key isEqual:@"expectedRaise"])
    {
        [self setExpectedRaise:0.0];
    }
    else
    {
        [super setNilValueForKey:key];
    }
}
 
- (void)encodeWithCoder:(NSCoder *)coder
{
    [coder encodeObject:personName forKey:@"personName"];
    [coder encodeFloat:expectedRaise forKey:@"expectedRaise"];
}
 
- (id)initWithCoder:(NSCoder *)coder
{
    [super init];
    personName = [[coder decodeObjectForKey:@"personName"] retain];
    expectedRaise = [coder decodeFloatForKey:@"expectedRaise"];
    return self;
}
 
@end

Chapter 11, Basic Core Data.

You thought it was good, well it just gets better. All the code we still had to write to add undo/redo, change tracking and archiving to our application can be done without writing any line as illustrated with this chapter. Again we see the power of Key-Value coding.

Chapter 12, Nib Files and NSWindowController.

Nib files contain the state of the window designed with interface builder, this chapter tells you how you can postpone loading a window/panel to save memory and resources. It also how you can load classes (this includes Windows, custom classes, etc.) by their name. Much like the Activator in .Net.

- (IBAction)showAboutPanel:(id)sender
{
    BOOL successful = [NSBundle loadNibNamed:@"About" owner:self];
    if(successful){
        NSLog(@"Loaded nib from NSBundle");
    }
    else{
        NSLog(@"Unable to load nib");
    }
}

RaiseMan – Chapter 9.zip (72.21 kb)

RaiseMan – Chapter 10.zip (74.18 kb)

CarLot – Chapter 11.zip (43.54 kb)

RaiseMan – Chapter 12.zip (85.23 kb)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.