views:

210

answers:

3

I have a nib that I load the usual way

[NSBundle loadNibNamed:@"AuthorizationWindow" owner:self];

and I see the window show on the screen briefly, and using NSLog() I can confirm that -awakeFromNib is called, but I can't figure out why the window does not stay on the screen. I had it working correctly for a bit, but now I'm not sure what I changed that messed it up. Thoughts of where to start looking?

A: 

I would take a closer look at the object you are using to load the nib (self, in the code you provided). Since it is the owner of the window, the window will be released when that object is released.

e.James
+3  A: 

I'd guess your window is being deallocated (or if under GC, collected) right out from under you. There are about a million possible reasons for this (none of which we can diagnose from one line of code), but there mere fact you're using +loadNidNamed:owner: is a warning flag. The reason is that items instantiated in nibs follow the same memory management rules as the rest of Cocoa; if you want them to stick around, you have to retain them (or in GC, keep a reference to them). NSWindowController (and NSViewController too) has some special nib-handling code so that it retains all the top-level objects in its nib when it loads, so that they'll stick around as long as it does*. However, if you don't use that, you have to do all that manually.

The real solution is: Don't use +loadNibNamed:owner:. Instead, create an NSWindowController subclass and set up its -init method like so:

@implementation AuthorizationWindowController
- (id)init
{
    self = [super initWithWindowNibName:@"AuthorizationWindow"];
    if (self == nil) return nil;
    // any other initialization code
    return self;
}

*It also has special code to handle bindings-induced retain cycles that would normally cause it to leak, which is quite a bit more difficult to write yourself. Yet one more reason to use NSWindowController.

Boaz Stuller
A: 

Turns out that I had enabled GC and that did it. Will give the window controller method a go. Thanks.

jxpx777