NSWindowController subclasses must override windowNibName for programmatically created windows
| Originator: | nathaniel.chandler | ||
| Number: | rdar://19289232 | Date Originated: | 2014-12-17 |
| Status: | Open | Resolved: | No |
| Product: | OS X SDK | Product Version: | 10.10.1 |
| Classification: | Enhancement | Reproducible: | Always |
Summary:
It certain circumstances, it would be desirable to create an NSWindowController subclass which doesn't have a corresponding XIB. One very sensible way to do this would be to override -loadWindow.
This works just fine if -windowNibName is implemented to return something non-nil. However, if one does not have a NIB, one would not expect to have to provide a NIB name.
This seems to be due to the implementation of -[NSWindowController isWindowLoaded] which apparently checks whether _wcFlags.nibIsLoaded is 0 and whether windowNibName is nil. Here's the decompilation from Hopper.app:
char -[NSWindowController isWindowLoaded](void * self, void * sel) {
rdi = self;
LOBYTE(rax) = 0x1;
if ((rdi->_wcFlags & 0x4) == 0x0) {
rax = [rdi windowNibName];
LOBYTE(rax) = rax == 0x0 ? 0x1 : 0x0;
}
LODWORD(rax) = LOBYTE(rax) & 0xff;
return rax;
}
which massages into
- (BOOL)isWindowLoaded {
BOOL result = YES;
if (!_wcFlags.nibIsLoaded) {
if ([self windowNibName] = nil) {
result = YES;
} else {
result = NO;
}
}
return result;
}
This means that if windowNibName is nil, isWindowLoaded returns YES.
When creating an NSWindowController subclass without a corresponding XIB file, if one only overrides loadWindow to programmatically create an NSWindow to assign to self.window but does not override windowNibName to return a non-nil object, loadWindow will never be called.
Steps to Reproduce:
1. Open the attached project. ( http://cl.ly/3Q3u162c0F17 )
2. Open WindowController.m and observe the implementation of windowNibName:
// COMMENT ME OUT!
- (NSString *)windowNibName
{
return @"nonsense";
}
3. Run the app. You will see a window presented.
4. Comment out windowNibName in WindowController.m.
5. Run the app. You will not see a window presented.
Expected Results:
An NSWindowController subclass which programmatically creates its window in loadWindow should function properly without windowNibName being non-nil.
Actual Results:
When creating an NSWindowController subclass that implements loadWindow to programmatically create a window, it is necessary to ensure that windowNibName is non-nil, either by overriding the method to return a non-nil value or by passing one to the initializer (-initWithWindowNibName:owner:).
Version:
Xcode 6.2 Beta 2, OS X 10.10.1.
Notes:
Configuration:
Attachments:
'ProgrammaticWindowControllerDemo.zip' was successfully uploaded.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!