Search code examples
iosobjective-cuitableviewuipopovercontroller

App crashes when UITableView clicked second time


MyVC* bottle = [[MyVC alloc] initWithDelegate:self];
bottle.title = @"bottle";

if ( water == nil )
    water = [[UIPopoverController alloc] initWithContentViewController:bottle];
else
    water.contentViewController = bottle;

This code runs once....when I click again on UITableViewCell my app crashes.. I am unable to figure it Out Why??

ERROR

 -[UIPopoverController setContentViewController:animated:] can only be called after the popover has been presented.'

NOTE When Change my code this to following it works:

MyVC* bottle = [[MyVC alloc] initWithDelegate:self];
bottle.title = @"bottle";

if ( water == nil )
    water = [[UIPopoverController alloc] initWithContentViewController:bottle];
else
    water = [[UIPopoverController alloc] initWithContentViewController:bottle];

But i uses memory as double allocation is present.How can I resolve this


Solution

  • You are making a confusion between initialisation, presentation, and content modification of your UIPopoverController.

    It is OK to store your popover on an instance variable, to avoid recreating it every time. It doesn't cause any trouble either to set the contentViewController to a new instance of "Bottle" if that "water" exists already.

    But your error messages says it all: -[UIPopoverController setContentViewController:animated:] : you are trying to change the content of your popover with an animation. It means, your popover must already be presented (i.e. visible). For doing so, use one of the two methods starting with presentPopoverFrom... before changing its content.

    In other words, only once your popover is presented, you can animate a change of content. Note also that it makes no sense to animate a change when your popover is not yet presented / visible. Use the setter .contentViewController = for that (or the non-animated method).

    A note on your edit/note: Writing the same allocation in the two branches of the if/else clause is pointless. And it doesn't cause the system to use twice memory. Because when the compiler sees the second line ("else"...), it first releases the existing instance of the popovercontroller before allocating the new one and making the "water" instance variable point to it.