I am trying to optimize the code in my app. I have quite a few ViewControllers which all use a common "keypad". I wanted to extract the keypad into a separate ViewController and then include it into the existing ViewControllers. This way I could obliviate duplicate code (which was needed to deal with the reactions from the keypad) in the separate ViewControllers.
So in the KeyPadVC I have methods set up that look something like this.
-(IBAction)keyPadKeyPressed:(id)sender
{
[self.delegate interpretKeyPressed:[[sender titleLabel] text]];
}
In my "parent" ViewControllers I include the keypad by adding a subview to a plain UIView that I placed in Interface Builder (so that I have a visual placeholder) and hooked up to the variable keypadView
.
-(void) viewDidLoad
{
[super viewDidLoad];
KeyPadViewController *kpVC = [[KeyPadViewController alloc] init];
[kpVC setDelegate: self];
[[self keypadView] addSubview:[kpVC view]];
}
This displays fine, but when I press a button on the KeyPadViewController I get a zombie object because the object was already released. I then tried to declare KeyPadViewController *kpVC
in the @interface
and tried a self instantiating method like:
-(KeyPadViewController *)kpVC
{
if (!kpVC) {
kpVC = [[KeyPadViewController alloc] init];
}
return kpVC;
}
I obviously modified the viewDidLoad
method, but the result was always the same. The object gets released too soon. If I add NSLogs I can see that -(IBAction)keyPadKeyPressed
from the KeyPadVC never gets called, because it KeyPadVC was already released.
What am I doing wrong? I am using ARC and iOS6 SDK.
Thanks
PS: this is pseudo-code to make things shorter - hope there are no typos - if so then that is not the issue. :)
KeyPadViewController *kpVC = [[KeyPadViewController alloc] init];
[kpVC setDelegate: self];
[[self keypadView] addSubview:[kpVC view]];
self.kpVC = kpVC;
That retains the view controller.
However, what you are doing is totally illegal because you are not using parent-child architecture. See my answer here: https://stackoverflow.com/a/15962125/341994
You can add a subview to your view, but you must not add a view controller's view as a subview to your view without going through the elaborate parent-child architecture. And you are not doing that.
I explain the parent-child architecture here:
http://www.apeth.com/iOSBook/ch19.html#_container_view_controllers