关闭popover,然后popToRootViewController,EXC_BAD_ACCESS
问题描述:
我碰到了,当我popToRootViewController
,这是我设置它的方式。关闭popover,然后popToRootViewController,EXC_BAD_ACCESS
我:
@property (nonatomic, retain) UIPopoverController *popover;
中的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。
答
你可能想改变self.popover = nill
到popover = nil
因为第一(self.popover = nil
)将调用属性setter,释放旧值并设置成员为零。另外,将属性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];
}
如果还是不行,在调试器设置NSZombieEnabled,MallocStackLogging和guard malloc。然后,当你的应用程序崩溃,在gdb的控制台输入:
(gdb) info malloc-history 0x543216
替换0x543216
与导致崩溃的对象的地址,你会得到一个更加有用的堆栈跟踪,它应该帮助你查明导致问题的代码中的确切行。
答
而且,你显式调用:在dealloc中
[popever release];
?因为你这样做:
self.popover = nil;
,将释放对象,你不必担心它在你的dealloc。但是,就像@chown说的那样,使用Instruments Zombie工具,它会马上告诉你发生了什么。
我会想象popover.delegate = nil; popover后=零;是毫无意义的。 – jbat100
@ jbat100它是,很好的捕获。更新回答) – chown
@chown malloc:使用标准记录器记录malloc堆栈到磁盘是什么意思? –