Ios 僵尸UIWebView,当它';从javascript调用alert()后,s立即解除分配

Ios 僵尸UIWebView,当它';从javascript调用alert()后,s立即解除分配,ios,objective-c,uiwebview,nszombie,Ios,Objective C,Uiwebview,Nszombie,我使用的是UIWebView,当点击按钮时,它会弹出一个警报(来自javascript)。还有另一个按钮(在本机端)用于关闭控制器,因此解除锁定也可以使用UIWebView 问题是,如果我在填充警报之前触摸UIWebView中的按钮,并触摸关闭按钮,我的控制器和UIWebView将被解除分配,但警报仍保留在屏幕上。然后,如果我单击任何警报按钮,应用程序将崩溃并出现以下错误: [UIWebView modalView:didDismissWithButtonIndex:]: message sen

我使用的是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,因为它是私有的

我怎样才能解决它


关于

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

这是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”]
是否为真,并取消该操作。这是一种不如前一种优雅的方法,应该是最后的手段


祝你好运。

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


我只是在这个函数中保留UIWebView实例,以便在释放UIAlertView实例之前,不会释放UIWebView实例作为UIAlertView的委托

我无法访问UIAlertView,因为它是由UIWebView私下处理的。您可以挂接UIAlertView委托函数。因此,您可以保留UIWebView以防止其过早发布。
- (void)didPresentAlertView:(UIAlertView *)alertView
{
    if ([self.delegate respondsToSelector:@selector(didPresentAlertView:)]) {
        [self.delegate didPresentAlertView:alertView];
    }
    if ([self.delegate isKindOfClass: [UIWebView class]]) {
        uiWebView = self.delegate;
    }
}