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. TheNSWindow
and the button are attached to the newMyClass
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
.
精彩评论