Scope Problem??

Discussion in 'Mac Programming' started by klkittel, Nov 22, 2011.

  1. klkittel, Nov 22, 2011
    Last edited by a moderator: Nov 22, 2011

    klkittel macrumors newbie

    Joined:
    Nov 10, 2011
    #1
    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?
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    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.
     
  3. klkittel thread starter macrumors newbie

    Joined:
    Nov 10, 2011
    #3
    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?
     
  4. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #4
    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.
     
  5. klkittel thread starter macrumors newbie

    Joined:
    Nov 10, 2011
    #5
    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.
     
  6. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #6
    Fine, but the code that you do post, please post the actual code.


    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.
     
  7. klkittel thread starter macrumors newbie

    Joined:
    Nov 10, 2011
    #7
    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
     
  8. jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #8
    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?
     
  9. klkittel thread starter macrumors newbie

    Joined:
    Nov 10, 2011
    #9
    Yes, is that the wrong way to do it?
     
  10. jiminaus, Nov 22, 2011
    Last edited: Nov 22, 2011

    jiminaus macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #10
    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.
     
  11. klkittel thread starter macrumors newbie

    Joined:
    Nov 10, 2011
    #11
    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.
     

Share This Page