解散popover,然后是popToRootViewController,EXC_BAD_ACCESS

时间:2011-11-16 22:23:33

标签: iphone

popToRootViewController时遇到了崩溃,这就是我设置它的方式。

我有:

@property (nonatomic, retain) UIPopoverController *popover;

in dealloc:

[popover release];

按下按钮时

if (self.popover == nil) {
    DetailViewController *detailView = [[[DetailViewController alloc] init] autorelease];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(GoToTest:) name:TestDetailPressed object:detailView];
    self.popover = [[[UIPopoverController alloc] initWithContentViewController:detailView] autorelease];
    self.popover.delegate = self;
    [self.popover presentPopoverFromRect:frame inView:self.scrollView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

我的DetailViewController基本上只是UITableView。当选择一行时,我会向GoToTest的当前类发回通知:

- (void)GoToTest:(NSNotification *)notification {
    if ([self.popover isPopoverVisible]) {
        [self.popover dismisspopoverAnimated:YES];
        [self handleDismissedPopover:self.popover];
    }
    [self.navigationController popToRootViewControllerAnimated:NO];
}

- (void)handleDismissedPopover:(UIPopoverController *)popoverController {
    self.popover = nil;
    self.popover.delegate = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TestDetailPressed object:nil];
}

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
    [self handleDismissedPopover:popoverController;
}

当我在乐器中运行时,我会收到

的僵尸消息
 -[UIPopoverController _popoverDismissAnimationCompleted]

并且UIViewController此时的refCt为-1。

2 个答案:

答案 0 :(得分:2)

您可能希望将self.popover = nill更改为popover = nil,因为第一个(self.popover = nil)将调用属性setter,后者会释放旧值并将成员设置为nil。另外,将代理nil置于属性nil之前。

要修复,请更改此内容:

- (void)handleDismissedPopover:(UIPopoverController *)popoverController {
    self.popover = nil;
    self.popover.delegate = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TestDetailPressed object:nil];
}

要:

- (void)handleDismissedPopover:(UIPopoverController *)popoverController {
    popover.delegate = nil;
    popover = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self name:TestDetailPressed object:nil];
}

如果这不起作用,请在调试器中设置NSZombieEnabledMallocStackLoggingguard malloc。然后,当您的应用程序崩溃时,请在gdb控制台中输入:

(gdb) info malloc-history 0x543216

0x543216替换为导致崩溃的对象的地址,您将获得更有用的堆栈跟踪,它可以帮助您查明代码中导致问题的确切行。

See this article for more detailed instructions.

答案 1 :(得分:0)

另外,您是否明确致电:

[popever release];

在dealloc?既然你这样做:

self.popover = nil;

将释放该对象,您无需在dealloc中担心它。但是,就像@chown说的那样,使用Instruments Zombie工具,它会马上告诉你什么事情。