Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacements for the deprecated NSNibLoading methods (loadNibFile:, loadNibNamed:, etc.)?

I have found that the NSNibLoading methods in NSBundle:

+[NSBundle loadNibFile:externalNameTable:withZone:]
+[NSBundle loadNibNamed:owner:]
-[NSBundle loadNibFile:externalNameTable:withZone:]

have all been marked deprecated in 10.8 - what is the proper way to load the nibs in 10.8 and later?

I'm trying to create a custom sheet in my app, do I have to create NSWindowController with initWithWindowNibName for the custom sheet?

like image 816
maseth Avatar asked Oct 07 '12 10:10

maseth


2 Answers

If your app is going to support Lion, then loadNibNamed:owner:topLevelObjects: will not fire and you'll get an exception (unrecognized selector) when run on Lion. After some searching around I came up with this:

    // loadNibNamed:owner:topLevelObjects was introduced in 10.8 (Mountain Lion).
    // In order to support Lion and Mountain Lion +, we need to see which OS we're
    // on. We do this by testing to see if [NSBundle mainBundle] responds to
    // loadNibNamed:owner:topLevelObjects: ... If so, the app is running on at least
    // Mountain Lion... If not, then the app is running on Lion so we fall back to the
    // the older loadNibNamed:owner: method. If your app does not support Lion, then
    // you can go with strictly the newer one and not deal with the if/else conditional.

    if ([[NSBundle mainBundle] respondsToSelector:@selector(loadNibNamed:owner:topLevelObjects:)]) {
        // We're running on Mountain Lion or higher
        [[NSBundle mainBundle] loadNibNamed:@"NibName"
                                      owner:self
                            topLevelObjects:nil];
    } else {
        // We're running on Lion
        [NSBundle loadNibNamed:@"NibName"
                         owner:self];
    }

If you really want to use topLevelObjects:&array for Mountain Lion +, and you also want to support Lion, it looks like you will need to fall back on loadNibFile:externalNameTable:withZone: (available as both a class and instance method) for the Lion condition (I could be wrong about this one). I'm getting the impression that loadNibNamed:owner:topLevelObjects: was created to replace this.

I've also read elsewhere that when using the newer loadNibNamed:owner:topLevelObjects: for a sheet that you should uncheck "Release When Closed" for the sheet (window). This should be taken care of when you close the sheet:

[self.sheet close];
self.sheet = nil;

I'm not sure exactly what should be done about that checkbox if you're opening a non-modal window. Any ideas?

like image 166
Dave Higgins Avatar answered Nov 09 '22 11:11

Dave Higgins


The NSBundle class method loadNibNamed:owner: is deprecated in OS X v10.8,
loadNibNamed:owner:topLevelObjects: is not and the comments in the documentation state why:

Unlike legacy methods, the objects adhere to the standard cocoa memory management rules; it is necessary to keep a strong reference to them by using IBOutlets or holding a reference to the array to prevent the nib contents from being deallocated.

like image 6
Jay Avatar answered Nov 09 '22 12:11

Jay