目标c-UIPopoverController内存崩溃



我现在花了好几天的时间试图弄清楚发生了什么,我一辈子都看不出自己做错了什么。当用户触摸屏幕上的某个点时,我会弹出一个UIPopover。popover有一个选项卡控制器和显示该点信息的表视图。但当popover被驳回时,它崩溃了,声称:-[UIAnimator removeAnimationsForTarget:]:消息发送到已解除分配的实例

以下是加载视图控制器的代码:

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;
}

实际的MyViewController只是一个UIViewController,它带有(为简洁起见,缩写为(init:

  - (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只不过是〔super Dealloc〕,因为所有东西基本上都归视图所有,视图控制器会处理它。当myPop在DidDismissPopover中发布时,视图也会被发布,所以这似乎可以正常工作。但不久之后,我就崩溃了。

当弹出窗口消失时,我需要做一些特殊的事情来放弃选项卡视图或表格视图吗?

我正在表中的单元格上使用自动释放酶,我应该停止这样做吗?

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

提前感谢您的帮助!!!任何想法都将不胜感激!!

-Kevin

[myPop dismissPopoverAnimated:YES]将继续访问对象,即使在方法调用之后也是如此,因为您为动画设置了YES(有一个计时器和其他东西在后台执行动画(

因此,您可以将其标记为autorelease以推迟此操作,而不是立即释放对象,这实际上可能会解决问题。

或者推迟到一个时间上映,这样你就可以确定动画会完成。你可以使用GCD(如果你使用的是iOS 4+(,由于UIKit中动画的默认时间是0.3秒,下面的代码应该可以做到这一点。

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];
});

编辑:您应该只将这段时间用于测试建议,因为这远不是发布对象的正确方式。

您应该存储一个指向UIPopover的指针,并在类dealloc方法中释放它。

在执行表信息->参数选项卡->环境变量中添加以下键

NSZombieEnabled = YES
CFZombie = 5
MallocStackLoggingNoCompact = 1

然后当你自动崩溃时,你会收到一条消息一些类似的东西

(gdb(继续

2011-06-09 11:46:08.404测试[6842:40b]*-[NSArrayIrelease]:消息发送到已解除分配的实例0X64a4900

然后键入

(gdb(信息malloc历史0x64a4900

它将给你完整的历史。

也许它能帮你找到那个地方。

也可以在崩溃时使用where命令。

避免等待动画结束的最快方法是在关闭弹出窗口或Popover Delegate方法时立即设置popoverController.delegate = nil

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController

被调用。

最新更新