In my attempt to learn Cocoa programming, I’m working on a tiny app to
practice saving and loading files. Each document window contains a
text field, a label, and a button. The user types a string into the
text field and clicks the button, and the same text appears in the
label. When the document is saved and reopened, the string that was
saved with the document should appear in the label. Apart from saving
and loading, the program works as I expect.

The app contains just one class (besides MyDocument), called
AppController. The code for AppController is pasted below, followed by
console output.

When loading a saved document, the application calls initWithCoder.
This decodes the saved string and uses it in the initWithString
method. According to log statements, the initWithString method is
called successfully. But then the program calls the generic init
method, which sets the string to NULL, so the label in the window
reverts to the null placeholder set in the xib file.

I don’t know what’s calling the generic init method, or how to prevent
this from happening, or if I should be avoiding this problem some
other way. Any explanation of this situation would be appreciated.

=== AppController.h ===
#import <Cocoa/Cocoa.h>


@interface AppController : NSObject <NSCoding> {
        NSString *theString;
        IBOutlet NSTextField *theInput;
}

@property (retain) NSString *theString;
-(IBAction)displayString:(id)sender;
-(id)initWithString:(NSString *)aString;

@end

=== AppController.m ===
#import "AppController.h"

@implementation AppController
@synthesize theString;

-(IBAction)displayString:(id)sender
{
        NSLog(@"displayString is being called");
        [self willChangeValueForKey:@"theString"];
        theString = [theInput stringValue];
        [self didChangeValueForKey:@"theString"];
}

-(void)encodeWithCoder:(NSCoder *)coder
{
        [coder encodeObject:theString forKey:@"theString"];
}

-(id)initWithCoder:(NSCoder *)coder
{
        NSString *aString = [[coder decodeObjectForKey:@"theString"] retain];
        NSLog(@"initWithCoder is being called");
        NSLog(@"aString is %@", aString);
        [self initWithString:aString];
        return self;
}

-(id)initWithString:(NSString *)aString
{
        if (self = [super init]) {
                NSLog(@"initWithString is being called with string %@", 
aString);
                [self willChangeValueForKey:@"theString"];
                theString = aString;
                [theString retain];
                [self didChangeValueForKey:@"theString"];
                NSLog(@"theString is %@", theString);
                return self;
        }
        else
                return nil;
}

-(id)init
{
        NSLog(@"generic init is being called");
        self = [super init];
        return self;
}
@end

=== console output from opening a file ===

2009-05-11 15:40:13.210 SaveTest2[26335:10b] readFromData called
2009-05-11 15:40:13.211 SaveTest2[26335:10b] initWithCoder is being called
2009-05-11 15:40:13.212 SaveTest2[26335:10b] aString is foo
2009-05-11 15:40:13.212 SaveTest2[26335:10b] initWithString is being
called with string foo
2009-05-11 15:40:13.212 SaveTest2[26335:10b] theString is foo
2009-05-11 15:40:13.215 SaveTest2[26335:10b] generic init is being called
2009-05-11 15:40:13.217 SaveTest2[26335:10b] windowControllerDidLoadNib called
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to