Reputation: 1989
I am using Xcode 4.6.3, and I have created a new project using the “Cocoa Application” template. The default structure seems a bit funny to me, and I was wondering if it is the recommended structure.
Specifically, three of the files created by the template are:
MainMenu.xib
AppDelegate.h
AppDelegate.m
The MainMenu.xib
file contains the main menu definition, and the definition of the main window. It seems strange to me to have the main window defined in a file called MainMenu.xib
. Is this the recommended place to define the main window?
I was expecting to see a files like MainWindow.h
, and MainWindow.m
subclassed from NSViewController
. The current structure created from the template would lead me to create handlers for the main window events in the app delegate. This also seems strange to me. Is it recommend to put the main window outlets and handlers in the app delegate?
Upvotes: 2
Views: 390
Reputation: 96373
One of the first things I do is rip that window out.
I was expecting to see a files like MainWindow.h, and MainWindow.m subclassed from NSViewController.
View controllers are not windows, and windows are not view controllers.
What I do (after deleting the window from the MainMenu nib) is create a window controller subclass, using the Objective-C Class file template and enabling the “and a nib, too, please” option (which appears when the superclass is NSViewController or NSWindowController).
(Don't forget to select the nib afterward and click the button in the File Inspector to make it localizable, since Xcode doesn't do that by default for some reason.)
In the implementation of the subclass, I have something like the following:
@implementation MyWindowController
- (instancetype) init {
return [self initWithWindowNibName:NSStringFromClass([self class])];
}
//and all my app-specific stuff
@end
In the app delegate, I delete the outlet that once referred to the MainMenu-born window, and then I create the window controller:
@implementation MyAppDelegate
{
MyWindowController *_wc;
}
- (void) applicationWillFinishLaunching:(NSNotification *)notification {
_wc = [MyWindowController new];
[_wc showWindow:nil];
}
- (void) applicationWillTerminate:(NSNotification *)notification {
[_wc close];
_wc = nil;
}
@end
(I use ARC; if you don't, you'll want to add a release
message in there.)
Is it recommend to put the main window outlets and handlers in the app delegate?
No. That is outside the scope of what the application's delegate should do.
For an extremely simple one-window app, you might want to make the window controller the application's delegate. But even that is different from making an app delegate that isn't a window controller handle actions, be a data source, etc. It's the difference between adding a little bit of responsibility to a window controller, and adding a whole lot of responsibility to an app delegate.
I keep them separate at all times. It's a bit of extra work in the simple cases, but my project is cleaner, which makes me happier, and I usually need to do it sooner or later anyway.
Upvotes: 2