【问题标题】:iPad ARC app crashing when UIPopoverController shown显示 UIPopoverController 时 iPad ARC 应用程序崩溃
【发布时间】:2013-06-27 23:22:19
【问题描述】:

当我尝试在我的 iPad 应用程序中显示弹出框控制器时,我收到了(显然很常见的)错误 [UIPopoverController dealloc] reached while popover is still visible.

这里有很多问题,但我的问题似乎有所不同。首先,我通过父视图控制器上的属性保持对弹出框控制器的强引用:

@property (strong, nonatomic) UIPopoverController* passcodePopover;

这是我实际呈现弹出框的代码(注意我使用的是第三方BZPasscodeViewController):

- (IBAction)adminConfig:(id)sender {
    self.passView = [[BZPasscodeViewController alloc] init];
    self.passView.title = @"Kiosk Administration";
    self.passView.text = @"Enter passcode:"; // TODO: localize
    self.passView.handler = ^(NSString *enteredPasscode, NSString **text, NSString **detailText, BOOL *detailTextHighlighted) {
        NSLog( @"password handler!" );
        return BZPasscodeViewControllerResultDone;
    };
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.passView];
    self.passView.contentSizeForViewInPopover = [BZPasscodeViewController defaultContentSizeForView];
    self.passView.modalInPopover = YES;
    UIPopoverController* uipc = [[UIPopoverController alloc] initWithContentViewController:navigationController];
    self.passcodePopover = uipc;
    [self.passcodePopover bz_presentPopoverInWindow:self.view.window animated:YES];
}

现在奇怪的是它似乎在调用 set 属性时崩溃了,这可以在这个堆栈跟踪 sn-p 中看到:

0   CoreFoundation                      0x01d2802e __exceptionPreprocess + 206
1   libobjc.A.dylib                     0x01165e7e objc_exception_throw + 44
2   CoreFoundation                      0x01d27deb +[NSException raise:format:] + 139
3   UIKit                               0x00573bf2 -[UIPopoverController dealloc] + 86
4   libobjc.A.dylib                     0x011799ff -[NSObject release] + 47
5   libobjc.A.dylib                     0x011780d5 objc_release + 69
6   libobjc.A.dylib                     0x01178fda objc_storeStrong + 39
7   Kiosk                               0x00047d59 -[SplashViewController setPasscodePopover:] + 57
8   Kiosk                               0x00047ad2 -[SplashViewController adminConfig:] + 802
...

但是,弹出框会在应用程序崩溃之前立即出现在模拟器中,因此它显然已经超过了当前调用。显然还有其他对setPasscodePopover: 的隐式调用发生在某处。

如果它提供任何见解,则上述方法是由手势识别器触发的。

【问题讨论】:

  • 当您将uipc 分配给它时,self.passcodePopover 是否可能尚未为零?它实际上指的是仍然可见的弹出框控制器吗?把NSLog("old popover controller = %@", self.passcodePopover)放在你的方法中self.passcodePopover = uipc之前,或者用断点检查。
  • 啊哈!我想你已经找到了一些东西。结果,正如我所料,self.passcodePopover 第一次为空。但显然我的方法不止一次被调用!可能是手势识别器。我想你已经解决了。 :)

标签: cocoa-touch automatic-ref-counting uipopovercontroller


【解决方案1】:

self.passcodePopover 不为零,当您将 uipc 分配给它时。它已经指向一个屏幕弹出控制器。当您将 uipc 分配给 self.passcodePopover 时,会释放旧的弹出框控制器,然后在其视图仍然可见时释放该控制器。

您需要弄清楚何时要关闭旧的弹出框。您可以在重新分配之前简单地关闭它:

[self.passcodePopover dismissPopoverAnimated:YES];
self.passcodePopover = uipc;

请注意,将dismissPopoverAnimated: 发送到 nil 是安全的(它没有效果),因此您甚至不必先检查它。

【讨论】:

  • 在我的例子中,手势识别器只是连续两次调用该方法,所以我不需要关闭前一个。我所需要的只是检查它是否已经设置,如果是,则返回。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多