如何在 viewWillDisappear 中安全地关闭正在加载的 UIWebView? [英] How to safely shut down a loading UIWebView in viewWillDisappear?

查看:8
本文介绍了如何在 viewWillDisappear 中安全地关闭正在加载的 UIWebView?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含 UIWebView 的视图,它正在加载谷歌地图(很多 javascript 等).我遇到的问题是,如果用户在 web 视图完成加载之前点击导航栏上的后退"按钮,我不清楚如何整齐地告诉 web 视图停止加载然后释放它,而不是发送到已释放实例的消息.我也不确定 web 视图是否喜欢它的容器视图在它完成之前消失(但如果用户在加载之前点击后退按钮,我别无选择).

I have a view containing a UIWebView which is loading a google map (so lots of javascript etc). The problem I have is that if the user hits the 'back' button on the nav bar before the web view has finished loading, it is not clear to me how to tidily tell the web view to stop loading and then release it, without getting messages sent to the deallocated instance. I'm also not sure that a web view likes its container view disappearing before it's done (but I've no choice if the user hits the back button before it's loaded).

在我看来WillDisappear 处理程序中我有这个

In my viewWillDisappear handler I have this

map.delegate=nil;
[self.map stopLoading];

这似乎可以处理大多数情况,因为取消委托会阻止它将 didFailLoadWithError 发送到我的视图控制器.但是,如果我在视图的 dealloc 方法中释放 Web 视图,有时(间歇性地)我仍然会收到一条消息发送到已释放的实例,这似乎与实际页面中运行的 javascript 有关,例如:

this seems to handle most cases OK, as nil'ing the delegate stops it sending the didFailLoadWithError to my view controller. However if I release the web view in my view's dealloc method, sometimes (intermittently) I will still get a message sent to the deallocated instance, which seems to be related to the javascript running in the actual page, e.g.:

-[UIWebView webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:]: message sent to deallocated instance 0x4469ee0

如果我只是不发布 webview,那么我就不会收到这些消息,尽管我猜我会泄露 webview.

If I simply don't release the webview, then I don't get these messages though I guess I'm then leaking the webview.

如果我不发送stopLoading"消息,而只是在 viewWillDisappear 中释放 webview,那么我会看到如下消息:

If I don't send the 'stopLoading' message, and simply release the webview within viewWillDisappear, then I see messages like this:

/SourceCache/WebCore/WebCore-351.9.42/wak/WKWindow.c:250 WKWindowIsSuspendedWindow:  NULL window.

可能相关,我有时(再次完全断断续续)得到一个丑陋的 heisenbug,单击其他视图导航栏上的后退按钮会弹出标题,但不会弹出视图.换句话说,我在堆栈上留下了视图 n 的标题,但显示的视图仍然是视图 n+1 (结果是你被困在这个屏幕上,无法回到根视图 - 你可以去另一个方向,即推送更多视图并弹回没有正确弹出的视图,只是不到根视图.唯一的出路是退出应用程序).在其他时候,相同视图上的相同推送和弹出序列可以正常工作.

Possibly related, I sometimes (again totally intermittent) get an ugly heisenbug where clicking the back button on some other view's navbar will pop the title, but not the view. In other words I get left with the title of view n on the stack, but the view showing is still view n+1 (the result is you're trapped on this screen and cannot get back to the root view - you can go the other direction, i.e. push more views and pop back to the view that didn't pop corrrectly, just not to the root view. The only way out is to quit the app). At other times the same sequence of pushes and pops on the same views works fine.

这个特别的让我发疯.我认为这可能与加载 Web 视图之前视图消失有关,即在这种情况下,我怀疑它可能会在内存上乱涂乱画并混淆视图堆栈.或者,这可能是完全不相关的并且是其他地方的错误(我从来没有能够在调试构建模式下重现它,它只会在我无法使用 gdb 观看它时发生在发布构建设置中:-).从我的调试运行来看,我认为我没有过度发布任何东西.而且我似乎只有在某个时候点击了具有 web 视图的视图时才能触发它,并且在那之后它不会立即发生.

This particular one is driving me nuts. I think it may be related to the view disappearing before the web view is loaded, i.e. in this case I suspect it may scribble on memory and confuse the view stack. Or, this could be completely unrelated and a bug somewhere else (i've never been able to reproduce it in debug build mode, it only happens with release build settings when I can't watch it with gdb :-). From my debug runs, I don't think I'm over-releasing anything. And I only seem to be able to trigger it if at some point I have hit the view that has the web view, and it doesn't happen immediately after that.

推荐答案

对此的变体应该可以解决泄漏和僵尸问题:

A variation on this should fix both the leaking and zombie issues:

- (void)loadRequest:(NSURLRequest *)request
{
    [self retain];
    if ([webView isLoading])
        [webView stopLoading];
    [webView loadRequest:request];
    [self release];
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{
    [self retain];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    [self release];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    [self release];
}

- (void)viewWillDisappear
{
    if ([webView isLoading])
        [webView stopLoading];
}

- (void)dealloc
{
    [webView setDelegate:nil];
    [webView release];
    [super dealloc];
}

这篇关于如何在 viewWillDisappear 中安全地关闭正在加载的 UIWebView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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