UIPopoverController dealloc被调用 - ARC环境

19

当我第二次显示一个弹出控制器(在关闭它后再重新显示)时,我遇到了以下错误:

Terminating app due to uncaught exception 'NSGenericException', reason: '-[UIPopoverController dealloc] reached while popover is still visible.'

堆栈跟踪只是一堆十六进制数,在每次 UIApplicationMain 处理时都会发生 SIGABRT 错误。这是由按钮触发的代码:

- (IBAction)createNewScore:(id)sender {
    if (self.pc)
        if (self.pc.popoverVisible)
            return;
        else
        // Breakpoint is hit here—crashes after this line
            [self.pc presentPopoverFromBarButtonItem:(UIBarButtonItem *)sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
    NGDocumentInfoViewController *documentInfoVC = [[NGDocumentInfoViewController alloc] initWithBlankDocumentTargetInManagedObjectContext:self.context];
    UINavigationController *navc = [[UINavigationController alloc] initWithRootViewController:documentInfoVC];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneCreatingNewScore:)];
    UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelCreatingNewScore:)];
    navc.navigationBar.topItem.leftBarButtonItem = doneButton;
    navc.navigationBar.topItem.rightBarButtonItem = cancelButton;
    CGSize popoverSize = CGSizeMake(documentInfoVC.view.bounds.size.width, documentInfoVC.view.bounds.size.height);
    documentInfoVC.contentSizeForViewInPopover = popoverSize;
    UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navc];
    popover.delegate = self;
    self.pc = popover;
    [popover presentPopoverFromBarButtonItem:(UIBarButtonItem *)sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
我只想保留popover以解决问题,但这是一个ARC环境,所以我没有retain。有没有办法可以修复这个错误(而不是为该文件关闭ARC并手动处理整个文件的内存)?
编辑:popover存储为ivar:
@property (strong) UIPopoverController *pc;

有没有人有解决这个问题的方案(或许是ARC override)?如CodaFi所建议,我会提交BR,但如果能提供一个解决方案就更好了,因为这是重大项目中的障碍。如果不可能,那我想我会自己动手解决。


你能否在 Xcode 的断点导航器底部使用“+”设置一个关于 -[UIPopoverController dealloc] 的符号断点,并查看调试器中它停在哪里?也许那里的堆栈跟踪可以提供一些关于是什么释放了你的弹出窗口的见解。 - Brad Larson
断点没有被明确命中。在崩溃之前,在UIApplcationMain处出现了暂停,这似乎表明它至少部分与运行循环有关。我倾向于将其称为ARC的一个低级错误。完整的堆栈跟踪:http://bit.ly/rTf7f0 - FeifanZ
createNewScore 是否在主线程上执行? - titaniumdecoy
是的,在这里没有明确的线程处理。如果存在线程,则应该在苹果的代码中而不是我的代码中。 - FeifanZ
只是一个小警告,与iOS的其他实现相比,UIPopover整体上都很糟糕。提交你的错误报告,但根据我从去WWDC的人听到的,苹果不会很快修复弹出窗口。 - CodaFi
您可以查看此帖子 https://dev59.com/CnE85IYBdhLWcg3wQxLG - RK-
2个回答

18

我遇到了同样的问题,并通过将弹出窗口控制器保留在强实例变量中,并在重置属性之前明确地将其解散,以建议的方式进行修复,在第二次运行操作时分配新的弹出窗口控制器。在您的示例中,您应该添加类似以下内容:

- (IBAction)createNewScore:(id)sender {
    if (self.pc) {
         [self.pc dismissPopoverAnimated:YES];
    }

只是创建实例变量对我有用。在弹出窗口之外触摸也会在以后解除它,以防您不想使用按钮。 - werm098

3
如果您的弹出视图(popover)被存储为强引用,它将无法释放。唯一可能释放它的情况是包含强引用的对象(例如您示例中的 self)也被释放。
我认为重要的问题是当弹出视图可见时您正在做什么。
如果您已经检查过了,那么这可能是一个框架错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接