Memory failure in UIPopoverController

I have invested days now, trying to understand what is happening, and for life I do not see what I am doing wrong. I display UIPopover when the user touches a point on the screen. The popover has a tab controller and a tabular view that displays information about this point. But when the popover is fired, it crashes, stating that: - [UIAnimator removeAnimationsForTarget:]: the message was sent to the freed instance

Here is the code loading the view controller:

MyViewController *popView = [[MyViewController alloc] init]; myPop = [[UIPopoverController alloc] initWithContentViewController:pop]; [popView release]; myPop.delegate = self; [airportPop setPopoverContentSize:popView.view.frame.size]; [airportPop presentPopoverFromRect:CGRectMake(location.x,location.y,1,1) inView:self.mainView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; - (void)dismissPopover { if( myPop != nil ) { [myPop dismissPopoverAnimated:YES]; [myPop.delegate popoverControllerDidDismissPopover:airportPop]; } } - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { [myPop release]; myPop = nil; } 

The actual MyViewController is simply a UIViewController, which is short for init brevity:

  - (id)init { self = [super init]; //create a newview self.view = popView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, POPUP_WIDTH, POPUP_HEIGHT)]; [popView release]; topBar = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, POPUP_WIDTH, 30)]; .... [popView addSubview:topBar]; [topBar release]; //create a table view self.table = [[UITableView alloc] initWithFrame:CGRectMake(0, 30, POPUP_WIDTH, POPUP_HEIGHT-30-49)]; table.delegate = table.dataSource = self; .... //create a tab bar tabBar = [[UITabBar alloc] initWithFrame:CGRectMake(0, POPUP_HEIGHT-49, POPUP_WIDTH, 49)]; tabBar.delegate = self; [popView addSubview:tabBar]; [popView addSubview:table]; [tabBar release]; [table release]; return( self ); } 

Dealloc is nothing more than [super dealloc], since everything essentially belongs to the view, and the view controller takes care of that. When myPop is released, in DidDismissPopover, the view is also released, so everything seems to be in order. But very soon after that I get a disaster.

Do I need to do something to drop the tab view or table view when the popup is rejected?

I use autorelease in cells in a table, should I stop doing this?

  cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; 

Thanks for any help !!! Any ideas are generally welcome!

Kevin

+4
source share
3 answers

[myPop dismissPopoverAnimated:YES] will continue to access your object even after calling the method, because you set YES for the animation (there is a timer and other things that go under the hood to do the animation for this)

So, instead of immediately releasing the object, you can mark it as auto-advertising to postpone this action, which could actually solve it or not.

Or postpone the release for a while afterwards to make sure the animation is complete. You can use GCD for this (if you are using iOS 4+), and by default the animation time in UIKit is 0.3 s, the code below should do the trick.

 double delayInSeconds = 0.3; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [myPop.delegate popoverControllerDidDismissPopover:airportPop]; }); 

EDIT: you should use this time only to offer a test, since it is far from the right way to release an object.

You must save the pointer to UIPopover and release it in your dealloc class.

+4
source

Add the following keys to yor Exectables info-> Argument tabs-> environment variables

 NSZombieEnabled = YES CFZombie = 5 MallocStackLoggingNoCompact = 1 

then upon automatic failure you will get a message something like this

(gdb) continue

2011-06-09 11: 46: 08.404 test [6842: 40b] * - [_ NSArrayI release]: the message was sent to the freed instance 0X64a4900

then enter

(gdb) info malloc-history 0x64a4900

he will give you the full story.

Maybe this will help you find a place.

you can also use the where command when you get a crash.

+3
source

The fastest way to avoid waiting for the animation to popoverController.delegate = nil is to set popoverController.delegate = nil as soon as you release the popup or Popover Delegate method

 - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController 

.

0
source

All Articles