On 01/09/2009, at 4:13 PM, BareFeet wrote:

To try to isolate the issue, I created a "Refresh" button and hooked it up to a refresh method in MyController. It just calls "init" (as below). When the program runs and instantiates a document that I open, debugging the init call shows the_document as nil. But when I click "Refresh" to call init again, it shows the_document as not nil and fileString is assigned correctly etc.

So perhaps it's a problem with the instantiation?

My code is below.

Thanks for your help with this. This is one thorn in a project port (from AppleScript Studio) that is otherwise going very well.

Tom

//  MyDocument.h

#import <Cocoa/Cocoa.h>

@interface MyDocument : NSDocument
{
}
@end


//  MyDocument.m

#import "MyDocument.h"

@implementation MyDocument
// usual template code
@end


//  MyController.h

#import <Cocoa/Cocoa.h>

@class MyDocument;

@interface MyController : NSObject
{
        IBOutlet MyDocument* the_document;
}

- (IBAction) refresh:(NSButton*)sender;

@end


//  MyController.m

#import "MyController.h"
#import "MyDocument.h"

@implementation MyController

- (IBAction) refresh:(NSButton*)sender
{
        [self init];
}


This is very suspect. You can't send a message to an object that hasn't already been inited, and you can't init twice. So one of those things is wrong here.

Why don't you just do:

- (IBAction) refresh:(id) sender
{
        NSLog( @"file string = %@", [the_document fileString]);
}

and see what you get?

- (id) init
{
        [super init];
        NSString* fileString = [[the_document fileURL] path];
        // more code that uses fileString
}

<the_document> is not going to be valid at init time, because your init method isn't initialising it. That's why it's nil. However, since the document is made for you, and the controller is loaded from the nib, you can't set it up here anyway. The nib load itself will set it up, assuming you have it connected in IB.

Also, as an aside, pay attention to the correct idiom for init methods:

- (id) init
{
        self = [super init];
        if( self )
        {
                // ... local ivar initialisation ...
        }

        return self;
}



The ivar <the_document> won't be valid until at least -awakeFromNib is called. That's the earliest point you can access it.

I think you're over-thinking this. Is MyController an object in the nib? If so, connect <the_document> to File's Owner and you're done. By the time your document is ready to use, the controller will be valid, exist, and be working. Init time for any of these objects is too early - debugging in there won't tell you much because at that time the nib hasn't been fully loaded so none of the outlets will have been set. Also, for most objects instantiated from a nib, -init isn't even called, -initWithCoder: is instead.

If on the other hand you're instantiating MyController in code, stop it, and just add it in IB. If you instantiate it yourself you have to connect up the outlets yourself, and in that case you're back to square one - trying to find the document without a reference to it. It can be done, but it's long-winded and unnecessary. Just instantiate the controller in the nib, wire up the outlet and you're done.

This is all thoroughly covered in the documentation on nib concepts.

--Graham





_______________________________________________

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