当popover仍然可见时,解除了Popover,[UIPopoverController dealloc] [英] Dismissing Popover, [UIPopoverController dealloc] reached while popover is still visible

查看:145
本文介绍了当popover仍然可见时,解除了Popover,[UIPopoverController dealloc]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的视图控制器中存在一个强属性的UIPopoverController。当用户在弹出窗口可见时旋转iPad时,我会关闭弹出框并将我的属性设置为nil。

I have a UIPopoverController stored in a strong property in my View Controller. When the user rotates the iPad while the popover is visible, I dismiss the popover and set my property to nil.

if (self.popover != nil) {
    [self.popover dismissPopoverAnimated:NO];
    self.popover.delegate = nil;
    self.popover = nil;
}

当代码变为self.popover = nil时,ARC尝试取消分配UIPopoverController,但它崩溃了,因为它应该仍然可见。

When the code gets to self.popover = nil, ARC attempts to dealloc the UIPopoverController, but it crashes because it is supposedly still visible.

如果没有崩溃,我应该如何解雇并取消弹出窗口?

How am I supposed to dismiss and nil out the popover without it crashing?

推荐答案

首先,建议检查弹出窗口是否正在显示,这样可以方便地检查是否已分配弹出窗口:

First off, it would be advisable to check if the popover is being presented, this will conveniently also check if it is allocated:

if ([self.popover isPopoverVisible]) {
    [self.popover dismissPopoverAnimated:NO];
}

现在,问题是,你没有获得委托回调 - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController 如果你以编程方式解除popover,但是你需要一个强大的popover引用,直到它不再可见。

Now, the issue is, you don't get the delegate callback - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController if you dismiss the popover programmatically like this, but you need a strong reference to the popover until it is no longer visible.

执行此操作的方法是将属性延迟设置为nil直到返回主运行循环,就像回到主运行循环一样,所有动画都将已完成,因此弹出窗口将不再可见。

The way to do this is delay setting the property to nil until you return to the main run loop, as when you get back to the main run loop, all animations will have finished and thus the popover will no longer be visible.

您需要将设置popover的代码设置为nil到另一种方法:

You will want to move the code setting the popover to nil into another method:

- (void)releasePopover {
    self.popover.delegate = nil;
    self.popover = nil;
}

然后,在你的旋转回调中,添加此方法以在主运行中触发循环,我喜欢通过向主运行循环添加一个调用操作来做到这一点:

Then, in your rotation callback, add this method to fire on the main run loop, I like to do this by adding an invocation operation to the main run loop:

if ([self.popover isPopoverVisible]){
    [self.popover dismissPopoverAnimated:NO];
    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
    [[NSOperationQueue mainQueue] addOperation:invocationOperation];
}

最后,为了清洁,你可能想要打电话给 -releasePopover 来自 - (void)popoverControllerDidDismissPopover :( UIPopoverController *)popoverController 回调。

Finally, for the sake of cleanliness, you will probably want to call -releasePopover from inside your - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController callback.

所以,把它们放在一起:

So, putting it all together:

- (void)releasePopover
{
    self.popover.delegate = nil;
    self.popover = nil;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if ([self.popover isPopoverVisible]){
        [self.popover dismissPopoverAnimated:NO];
        NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil];
        [[NSOperationQueue mainQueue] addOperation:invocationOperation];
    }
}

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

说了这么多,除非有充分的理由,你可能只想要保持popover可以重复使用,只有当你得到低内存警告时和/或你的视图被卸载时才将其设置为nil,正如Chris Loonam的回答所提到的那样

Having said all that, unless there is a good reason, you may just want to keep the popover around to reuse and only set it to nil when you get low-memory warnings and/or if your view is unloaded, as Chris Loonam's answer mentioned

这篇关于当popover仍然可见时,解除了Popover,[UIPopoverController dealloc]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆