Re: Two controllers in a window, how do I get one to run a function in another?
Re: Two controllers in a window, how do I get one to run a function in another?
- Subject: Re: Two controllers in a window, how do I get one to run a function in another?
- From: Graham Cox <email@hidden>
- Date: Tue, 1 Sep 2009 16:36:48 +1000
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 (email@hidden)
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:
This email sent to email@hidden