views:

109

answers:

2

I have the following code:

@interface AXWindowController : NSWindowController {
IBOutlet NSTextField *text;
IBOutlet NSTextField *otherText;
}

- (void) setText: (NSString *)input;
- (void) setOtherText;

@end

@implementation AXWindowController

- (void) setText: (NSString *)input
{
    [text setStringValue:input];
}

- (void) setOtherText
{
    [otherText setStringValue:@"nag"];
}

@end

And when I run:

1. [controller showWindow:nil];
2. [controller setText:@"lol"];
3. [controller setOtherText];

Line 3 executes correctly, but line 2 does nothing. In fact, when I look at text and otherText in gdb while executing lines 2 and 3, I get the following results:

(gdb) p text
$1 = (NSTextField *) 0x0
(gdb) p otherText
$2 = (NSTextField *) 0x1385d1e0

What is happening? I can't pass in the input variable to a set function for an NSTextField? Why is my NSTextField becoming null when I change the parameters of the set function?

+1  A: 

To get the annoying, obvious responses out of the way, are you sure you've connected that IBOutlet in Interface Builder? When are you trying to set the lines of text--are you doing it in -awakeFromNib?

Preston
I have connected the IBOutlet in Interface Builder; I tried to connect the File's owner to the text field and then added an object, set it to AXWindowController, and connected that to the text field. Both product the same results. I am setting the lines of text from another function, not -awakeFromNib.
Chetan
And the weirdest part is that if I remove the parameter `input` and just set `text` to a predefined value, the problem goes away. Adding an `NSString` parameter, and not even using it, causes this problem. Please help!
Chetan
If not in -awakeFromNib, when are you calling the method that's trying to change the text? Just trying to make sure you're not attempting to use the outlet before it's been set up.
Preston
+4  A: 

It's well known KVC issue.

When Cocoa loading your NIB to connect outlets connections designed in IB, it will look for setter. So, it calls setText: with NSTextField* object while loading. Since your code not ready to accept different kind of objects... first for configure outlet, second for set its internal text value... your outlet will stay equal to nil.

All calls to nil - does nothing.

Workaround: rename outlet variable name or rename setter/getter methods to be different from KVC notation...

UncleMiF
Ah, you're right. They really should fix that or make it clear that we shouldn't use `setVARIABLENAME` notation in this sort of situation.
Chetan
I thought the same... However, after some review, I decided that they are absolutely right:While **setText:** - uses for set text variable by itself,**setTextValue:** - uses for configure text variable internal state...
UncleMiF