I have the following files:
Main.storyboard
This is the same as the default storyboard created when creating a new project with a few additions: There is a button in the view which is connected to the button
outlet of the view controller (instance of ViewController
) and the doTheThing:
action on the view controller.
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@property (weak) IBOutlet NSButton *button;
@property (weak) NSViewController *controller;
@end
@implementation ViewController
- (IBAction)doTheThing:(id)sender {
if (self.controller) {
NSLog(@"Removing %@", self.controller);
[self.controller.view removeFromSuperview];
[self.controller removeFromParentViewController];
} else {
self.controller = [[NSStoryboard storyboardWithName:@"Another" bundle:[NSBundle mainBundle]] instantiateInitialController];
[self addChildViewController:self.controller];
[self.view addSubview:self.controller.view];
NSLog(@"Adding %@", self.controller);
}
}
@end
Another.storyboard
A simple storyboard containing a single scene (view controller + view) that is set to the initial controller and is an instance of AnotherViewController
. There is a label in the view that is not connected to any outlet.
AnotherViewController.m
#import "AnotherViewController.h"
@interface AnotherViewController ()
@property (weak) IBOutlet NSTextField *label;
@end
@implementation AnotherViewController
- (void)dealloc {
NSLog(@"Deallocing AnotherViewController %@", self);
}
@end
When I run the app and click the button, it adds the view controller and view from Another.storyboard
, and when I click the button again they are removed and the instance of AnotherViewController
is deallocated.
However, if I connect the label in Another.storyboard
to the label
outlet on the AnotherViewController
, the deallocation never occurs. Why is this and what can I do to fix it?
Edit: I do have a few workarounds, but they aren't very desirable and I would prefer to understand why the recommended way (storyboards and outlets) isn't working properly.
Undesirable workaround 1: Do the same thing but load the view controller and view from a XIB file. This works as expected, but ideally I would be able to do the same thing using storyboards.
Undesirable workaround 2: Bind all my outlets manually in code in the view controller's viewDidLoad
method. This is just tedious and ugly as it requires iterating through all the view's subviews and comparing identifiers.
Apple have confirmed (via bug report) that this is a known issue and will be fixed in OS X 10.10.3.