问题
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?
回答1:
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.
回答2:
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?
来源:https://stackoverflow.com/questions/12767838/replacements-for-the-deprecated-nsnibloading-methods-loadnibfile-loadnibnamed