1

我正在使用 UIWebView,它会在单击按钮时弹出警报(来自 javascript)。还有另一个按钮(在本机端),它关闭控制器,所以也释放 UIWebView。

问题是,如果我触摸 UIWebView 中的按钮,并在填充警报之前触摸关闭按钮,我的控制器和 UIWebView 将被释放,但警报仍保留在屏幕上。然后,如果我单击警报上的任何按钮,应用程序将崩溃并给出以下错误:

[UIWebView modalView:didDismissWithButtonIndex:]: message sent to deallocated instance

并且这个方法是从私有方法中调用的

[UIModalView(Private) _popoutAnimationDidStop:finished:]

我正在使用ARC,我的dealloc是这样的:

- (void)dealloc {
    [_myWebView stopLoading];
    _myWebView.delegate = nil;
    _myWebView = nil;
}

但这并不能解决我的问题,因为我认为 UIModalView 将我的 webview 引用为委托,并且我无法将其设置为 nil,因为它是私有的。

我该如何解决?

问候

4

3 回答 3

1

这是他们处理警报视图的 Apple 错误。打开错误报告。

与此同时,这里有一些解决方法:

在 UIAlertView 上创建一个类别:

@interface UIAlertView (QuickDismiss) @end

@implementation UIAlertView (QuickDismiss)


- (void)__quickDismiss
{
     [self dismissWithClickedButtonIndex:self.cancelButtonIndex animated:NO];
}

@end

现在,在您的视图控制器的 dealloc 方法中,调用它:

[[UIApplication sharedApplication] sendAction:@selector(__quickDismiss) to:nil from:nil forEvent:nil];

这将关闭当前打开的所有警报视图,包括您的 Web 视图显示的那些。

如果这不起作用,您始终可以迭代所有UIApplication.sharedApplication.windows对象的所有子视图,检查是否[view.class.description hasPrefix:@"UIAlertView"]为真,然后将其关闭。这是一种不如前一种优雅的方法,应该是最后的手段。

祝你好运。

于 2013-08-24T16:01:26.630 回答
1

在解除分配 UIWebView 之前,找到一种将 UIAlertView 上的委托设置为 nil 的方法。

于 2013-04-09T11:34:39.363 回答
0

最后,我找到了一个非常有效的解决方案。我使用方法 swizzle 来挂钩 UIAlertView 委托功能 - (void)didPresentAlertView:(UIAlertView *)alertView

- (void)didPresentAlertView:(UIAlertView *)alertView
{
    if ([self.delegate respondsToSelector:@selector(didPresentAlertView:)]) {
        [self.delegate didPresentAlertView:alertView];
    }
    if ([self.delegate isKindOfClass: [UIWebView class]]) {
        uiWebView = self.delegate;
    }
}

我只是在这个函数中保留了 UIWebView 实例,这样 UIWebView 实例作为 UIAlertView 的委托就不会在 UIAlertView 实例被释放之前被释放。

于 2017-06-18T08:09:36.723 回答