开发者

Nib's IBOutlets are not connected (nil)

I have a Custom class which is supposed to load a window from a nib file. When I load the nib file everything looks fine except the IBOutlets are not connected i.e. nil. IBActions work fine and when they are called the IBOutlets are not nil anymore.

The class is added to the nib in the 开发者_运维技巧IB as an object and obviously everything wired up.

It's the file's Owner and delegate

When it loads the nib, the window appears only if its "visible at launch" is set.

It doesn't matter where I load the nib and try to access IBOutlets immediately or seconds later.

It must be something very trivial...

UPDATE2: I UPLOADED AN EVEN SIMPLER TRIAL PROJECT: Trial Project2

Expected behaviour: Window2 title changes to "Title has Changed x times" when loads. It only starts working once the button is pressed i.e. IBOutlets are not nil anymore.


The big change was subclassing NSWindowController to create MyClass. This way, you only attempt to manipulate the close button after the window has loaded. Your code was small enough that I thought it best to simply post the changes:

trialProjectAppDelegate.m

#import "trialProjectAppDelegate.h"

@implementation trialProjectAppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    myclass = [[MyClass alloc] init];
    // Note that I'm forcing the window to load here.
    (void) [myclass window];
}

@end

MyClass.h

#import <Cocoa/Cocoa.h>

@interface MyClass : NSWindowController
{
    IBOutlet NSButton *dismissButton;
}

- (IBAction)closeNaggingWindow:(id)sender;
- (void)disableDismissButton;

@end

MyClass.m

#import "MyClass.h"

@implementation MyClass

- (id)init
{
    if ((self = [super initWithWindowNibName:@"Window"]) != nil)
    {
    }

    return self;
}

- (void)disableDismissButton
{
    [dismissButton setEnabled:NO];
    [dismissButton setTitle:@"Closing enabled in 5 sec"];

    [self performSelector:@selector(enableDismissButton:) withObject:nil afterDelay:5];
}

- (IBAction)enableDismissButton:(id)sender
{
    [dismissButton setEnabled:YES];
    [dismissButton setTitle:@"Close"];
}

- (IBAction)closeNaggingWindow:(id)sender
{
    [[self window] close];
    [self autorelease];
}

- (void)awakeFromNib
{
    [self disableDismissButton];
}

@end

Finally, in your Window.xib file, discard the naggingWindow outlet and connect your window to the window outlet that NSWindowController provides.


I haven't worked with any of the OS X interface classes, so there may be some aspect of this that is not 100% precisely accurate, but basically what is happening is this:

You've wired your nib's NSWindow object to a MyClass object, which is also in your nib. So when you load that nib, here's what's happening:

  • A MyClass instance is created
  • An NSWindow instance is created, with several subviews. The NSWindow and the button are attached to the new MyClass instance.
  • Nothing is wired to the File's Owner pseudo-object (the MyClass instance you created in your app delegate)

Then -changeWindowTitle is called on your original MyClass instance, which has none of its outlets wired.

The solution is simple: remove the MyClass object from your nib file. Select the "File's Owner", and in the Identity Inspector (third icon from the left in the Utility pane) set "Class" to "MyClass". Now reconnect your outlets to the File's Owner object, which is your original MyClass instance. You should now see the behavior you expected.

As an aside, the right place to do things "as soon as the nib is loaded", like setting properties on your fresh IBOutlet objects, is in the method -windowDidLoad.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜