Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

klkittel

macrumors newbie
Original poster
Nov 10, 2011
12
0
Hello,

Here is the code to a problem that is driving me nuts.

TextEditorWindowController.h:

Code:
#import <Cocoa/Cocoa.h>


@interface TextEditorWindowController : NSWindowController {

	NSTextView	*editorTextView;
}

@property (nonatomic, retain)NSTextView	*editorTextView;

- (void)helloKitty;

@end

TextEditorWindowController.m:

Code:
#import "TextEditorWindowController.h"


@implementation TextEditorWindowController

@synthesize editorTextView;


- (void)dealloc {
	[editorTextView release];
	[super dealloc];
}


- (void)helloKitty
{
	[editorTextView setString:@"Hello Kitty"];
}

- (void) awakeFromNib
{	
	[editorTextView setString:@"Hello"];	
}

- (id)init
{
    self=[super initWithWindowNibName:@"TextEditor"];
    if(self)
    {
		// Do init here
    }
    return self;
}

@end

ExampleWindow.h:

Code:
#import <Cocoa/Cocoa.h>
#import "TextEditorWindowController.h"

@interface ExampleWindow : NSWindowController {

	TextEditorWindowController *	winController;
}

@property (nonatomic, retain) TextEditorWindowController	*winController;


@end


ExampleWindow.h

Code:
#import "ExampleWindow.h"
#import "TextEditorWindowController.h"

@implementation ExampleWindow

@synthesize winController;

// Other code here that opens the main window of the example

- (IBAction)newFile:(id)sender
{
	// Open the New Window

    winController = [[TextEditorWindowController alloc] init];
    [winController showWindow:self];
	
    [winController helloKitty];
}

- (void)dealloc
{
    [winController release];
    [super dealloc];
}

@end


Anyhow, the window is displayed, and the "Hello" message appears in the text view. But when I make the call to helloKitty the message "Hello Kitty" is not printed. The pointer editorTextView is zero, so the message does not print. It is as if something has been autoreleased or a new object was created (not passing the same object). The method helloKitty IS called, it is just that the pointer is zero, as I mentioned. What am I doing wrong?
 
Last edited by a moderator:
First, your editorTextView isn't declared as an IBOutlet. That suggests it's not connected to any outlet from the nib file. Therefore, editorTextView will not be assigned anything when the nib is loaded. And that means it remains at its initial default value: nil.

Second, do you know why editorTextView contains "Hello"? Is it because your awakeFromNib method runs, and sets it to "Hello"? Or might it be because the nib has a text view whose initial value is "Hello"? If you can't tell, then I suggest this change:
Code:
- (void) awakeFromNib
{	
  [editorTextView setString:@"Awake from nib"];	
}
If you don't see "Awake from nib", then you need to think about the IBOutlet.

Third, why don't you add NSLog calls to the awakeFromNib and helloKitty methods so you can actually see them being called. And a good thing to log would be the value of editorTextView, to see if it's nil.


If you don't know what an IBOutlet is, nor how to connect nib objects to outlet references in an object, you should go back and review the fundamentals of nibs.
 
Sorry, I was trying to cut down the code, and I left out the IBOutlet keywords. I DO have them in, and the nib is pointing to the IBOutlet correctly. At least I think it is. I've been over that several times.

The "hello" message is from the call in awakeFromNib: -

[editorTextView setString:mad:"Hello"];

and I have NSLogs in there too, and they DO fire and print the expected message. The pointer to editorTextView is zero or nil in the call to hellokitty and I don't understand why.

BTW how are you getting your code snippets to display in a separate box for this forum?
 
Please copy and paste code. It's frustrating to try to diagnose code when we're not looking at the actual code.

Surround your code with [CODE] and [/CODE]. You can do that by highlighting the code after you paste it and then clicking the # button in the post editor's toolbar.
 
The actual code is too big to post and contains too much code that doesn't pertain to this problem.

Here is a clue: the
Code:
NSLog(@"Awake from nib");
message is printed twice.
 
The actual code is too big to post and contains too much code that doesn't pertain to this problem.

Fine, but the code that you do post, please post the actual code.


Here is a clue: the
Code:
NSLog(@"Awake from nib");
message is printed twice.

So you do have two instances involved. Change that line to these two lines:
Code:
NSLog(@"Awake from nib: self = %p", self);
NSLog(@"self.editorTextView = %p", self.editorTextView);
This will be print the address of the object being sent awakeFromNib: also print the address of self.editorTextView at the time.

Also after you alloc/init winController add:
Code:
NSLog(@"winController = %p", winController);
This way we know which of those two instances are the one created here.
 
Here is the NSLog output. The second time that the window is instantiated the pointer goes to nil. I don't understand how I am instantiating the window twice. I only set it up once.

Code:
2011-11-22 22:38:03.864 Rufus[20747:a0f] winController = 0x0
2011-11-22 22:38:03.869 Rufus[20747:a0f] Awake from nib: self = 0x1001bb370
2011-11-22 22:38:03.869 Rufus[20747:a0f] self.editorTextView = 0x100691da0
2011-11-22 22:38:03.870 Rufus[20747:a0f] Awake from nib: self = 0x100189e70
2011-11-22 22:38:03.871 Rufus[20747:a0f] self.editorTextView = 0x0
[Switching to process 20747]
2011-11-22 22:38:11.520 Rufus[20747:a0f] Hello Kitty: self = 0x100189e70
2011-11-22 22:38:11.521 Rufus[20747:a0f] self.editorTextView = 0x0
 
Here is the NSLog output. The second time that the window is instantiated the pointer goes to nil. I don't understand how I am instantiating the window twice. I only set it up once.

Code:
2011-11-22 22:38:03.864 Rufus[20747:a0f] winController = 0x0
2011-11-22 22:38:03.869 Rufus[20747:a0f] Awake from nib: self = 0x1001bb370
2011-11-22 22:38:03.869 Rufus[20747:a0f] self.editorTextView = 0x100691da0
2011-11-22 22:38:03.870 Rufus[20747:a0f] Awake from nib: self = 0x100189e70
2011-11-22 22:38:03.871 Rufus[20747:a0f] self.editorTextView = 0x0
[Switching to process 20747]
2011-11-22 22:38:11.520 Rufus[20747:a0f] Hello Kitty: self = 0x100189e70
2011-11-22 22:38:11.521 Rufus[20747:a0f] self.editorTextView = 0x0

Did you log winController after the alloc/init of TextEditorWindowController. If strange that it's nil.

We can deduce that the TextEditorWindowController alloced/inited from newFile: and assigned to winController is 0x100189e70 because self in the call to helloKitty is 0x100189e70.

However, if we look back you can see that self.editorTextView is nil in the instance of TextEditorWindowController at 0x100189e70. But before that instance gets an awakeFromNib: message, another instance at 0x1001bb370 gets an awakeFromNib: message and furthermore that instance's self.editorTextView is not nil.

So you have an TextEditorWindowController object in your .xib don't you? And the text view in the .xib is connected to that object's editorTextView isn't it?
 
So you have an TextEditorWindowController object in your .xib don't you? And the text view in the .xib is connected to that object's editorTextView isn't it?

Yes, is that the wrong way to do it?
 
Yes, is that the wrong way to do it?

Yes, because you're introducing a new, distinct object. What you want to do is remove the object, set the class of the File's Owner placeholder object to TextEditorWindowController, and connect the text view to that object's editorTextView. At runtime, the instance of TextEditorWindowController of your alloc/init in newFile: will take the place of the File's Owner.
 
Last edited:
That was it! Thank you very much. Interface Builder is very confusing to me and there seems to be very poor documentation on using it correctly.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.