سؤال

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top