I did not dive into the storyboards, but here's how it works:
If your application must support 10.9 and below create a custom subclass of NSWindowController

Put this code in a subclass of NSDocument
- (void)makeWindowControllers { CustomWindowController *controller = [[CustomWindowController alloc] init]; [self addWindowController:controller]; }
If your application has several windows, than adding them here or somewhere else (loaded on demand), but do not forget to add it to the windowscontroller document array (addWindowController :)
If you create them, but do not want to show all windows, then redefine
- (void)showWindows { [controller showWindow:nil] }
You can access your model at any time in your window controller.
- (CustomDocument *)document { return [self document]; }
Use the bindings in your window controller (subclass of the windowcontroller subclass + document in the key path, which is a property of the window controller)
[self.textView bind:@"editable" toObject:self withKeyPath:@"document.readOnly" options:@{NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName}];
Unlike iOS, most views are on the screen, so you have to rely on templates: delegation, notification, events (responder chain) and, of course, MVC.
10.10 Yosemite Changes:
Starting from 10.10 , NSViewController is automatically added to the responder chain (usually the purpose of the action is unknown | NSApp sendAction: to: from :) and all delegates, such as viewDidLoad ... familiar with iOS, are finally implemented. This means that I no longer see the big benefits of subclassing NSWindowCotroller.
A subclass of NSDocument is required and NSViewController is sufficient.
You can access data at any time in the view controller
- (CustomDocument *)document { return (CustomDocument *)[[NSDocumentController sharedDocumentController] documentForWindow:[[self view] window]];
If you do this (according to KVC / KVO), you can do the binding as above.
Tips: Correctly implement UNDO for your model objects in a document, for example. or shamefully call updateChangeCount:
[[self.undoManager prepareWithInvocationTarget:self] deleteRowsAtIndexes:insertedIndexes];
Do not put code associated with views / windows in a document
Split your application into several NSViewControllers, for example.
- (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:AAPLListWindowControllerShowAddItemViewControllerSegueIdentifier]) { AAPLListViewController *listViewController = (AAPLListViewController *)self.window.contentViewController; AAPLAddItemViewController *addItemViewController = segue.destinationController; addItemViewController.delegate = listViewController; } }
The previous code is called in the windowcontroller with the viewcontroller as a delegate (again only possible after 10.10)
I always prefer to use multiple XIBs rather than one giant storyboard / XIB. Use the following subclass of NSViewController and always inherit it:
- Add a subclass of MyViewController to the project using XIB. Rename XIB
- Add NSViewController to XIB and change its subclass name

- Change the XIB name of the boot to the name from step 1

- Link to replace the view you want to replace
Example Example Example Project Multi XIB
Inhale yourself shapeart or lister or TextEdit
And the real guide is to use Hopper and see how other applications are made.
PS: You can add your views / viewcontroller to the responder chain manually.
PS2: If you are a beginner, do not reverse engineer. Be pleased that your application works.