【问题标题】:UIWebView not stopping immediatelyUIWebView 没有立即停止
【发布时间】:2015-10-09 10:03:42
【问题描述】:

我已经尝试了所有这些(onetwothreefour)解决方案,但是当我从 web 视图屏幕返回到上一个 viewController 后,它冻结了大约 2 秒(有时更多) . viewWillAppear 中没有任何内容会导致冻结。

这里是 Web 视图控制器的 viewWillDisappear

-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [detailWebView stopLoading];
    detailWebView.delegate = nil;
    NSLog(@"viewWillDisappear called !!!");
}

第一个视图控制器:

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:41.0/255.0 green:151.0/255.0 blue:132.0/255.0 alpha:1.0]];
    UIImage *imagePlus = [[UIImage imageNamed:@"create.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    buttonCreate = [UIButton buttonWithType:UIButtonTypeCustom];
    [buttonCreate setImage:imagePlus forState:UIControlStateNormal];
    [buttonCreate addTarget:self action:@selector(createActivity:) forControlEvents:UIControlEventTouchUpInside];
    buttonCreate.frame = CGRectMake(self.view.frame.size.width - 40, 10, 16, 16);
    [self.navigationController.navigationBar addSubview:buttonCreate];
    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"back", nil) style:UIBarButtonItemStylePlain target:nil action:nil];
    [backButton setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor blackColor]} forState:UIControlStateNormal];
    self.navigationItem.backBarButtonItem = backButton;
    [self.navigationController.navigationBar setTintColor:[UIColor blackColor]];
}

更新:我刚刚确认,如果我让 webView 完全加载然后转到上一个 viewController,则没有观察到冻结。

【问题讨论】:

  • 您确定是[detailWebView stopLoading]; 造成了延迟吗?你能评论一下,然后检查它是否运行顺利
  • @InderKumarRathore :刚刚检查过。 stopLoading 会停止 webview,但仍然需要一些时间才能停止。
  • 我要求评论这一行,看看是否有一些滞后?
  • @InderKumarRathore :如果我评论 stopLoading,延迟会增加。
  • 使用 Time Profiler 运行您的应用程序,以确保瓶颈在您认为的位置以及代码的哪一部分触发它。您还可以发布您如何加载网络视图吗?只是想放弃这是多线程问题的可能性。

标签: ios uiviewcontroller uiwebview


【解决方案1】:

viewWillDisappear试试这个:

-(void)viewWillDisappear:(BOOL)animated {  
  [detailWebView setDelegate:nil];
  [detailWebView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString:@""]]];
  [detailWebView stopLoading];
  [super viewWillDisappear:animated];
}

【讨论】:

  • 是的,它正在被调用。
  • 没有Mrunal,我没有。
【解决方案2】:

我执行以下操作,这与 @Mrunal 的建议类似,但会加载有效页面。我最初添加它是为了处理加载页面的计时器在从 UIWebView 弹出后继续永远运行的情况。对我来说这很好用。

- (void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    // Load a blank page as found things hang around.
    [self.theWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
}

NB 我不打电话给stopLoading,因为这会停止加载请求。这可能是 Mrunal 的解决方案有什么问题?

【讨论】:

  • 我们加载@"<html><body></body></html>"而不是about:blank,因为我们注意到内存以这种方式释放得更好。
【解决方案3】:

您是否使用 NSURLProtocol 来拦截来自您的 UIWebView 的 Web 请求?以下答案是基于该假设编写的。

网页的加载涉及发送对多个资源(图像、视频、html、javascript)的请求。这些资源中的每一个都有一个将被 NSURLProtocol 拦截的 URL

现在,如果您在加载所有资源之前关闭 webView,NSURLProtocol 有时会取消它正在拦截的所有打开的资源请求,并在此过程中冻结您的应用程序。

在退出 webView 之前,您将从 NSURLProtocol 注销。所以

 override func viewWillDisappear{
   NSURLProtocol.unregisterClass(/*your custom url protocol class name here*/)
  }

应该解决冻结问题

PS:有时您可能为整个应用程序定义了 NSURLProtocol,在这种情况下,我认为最好将 UIwebView 的 NSURLProtocol 与应用程序的其余部分分开。我对你的项目了解不多,如果这对你来说是一个可行的选择,我可以发表评论

【讨论】:

    【解决方案4】:

    我认为 webview 可能仍在后台处理。而且我体验到完全发布一个 UIWebView 是很烦人的。你可能想看看 Profiler:打开并关闭 webview 的 ViewController 几次,缓冲区应该会稳步增加。

    这就是为什么我想出合并几种解决方案,从堆栈溢出到最终完全从 web 视图中删除所有存储并阻止它运行。

    至关重要的是,将 webview 设置为 nil,以真正释放它的内存,以前我们有 release 方法,如果你正确使用 ARC,现在它已经“过时”了。

    - (void)releaseWebView:(UIWebView *)webView
    {
        /*
    
         There are several theories and rumors about UIWebView memory leaks, and how
         to properly handle cleaning a UIWebView instance up before deallocation. This
         method implements several of those recommendations.
    
         #1: Various developers believe UIWebView may not properly throw away child
         objects & views without forcing the UIWebView to load empty content before
         dealloc.
    
         Source: http://stackoverflow.com/questions/648396/does-uiwebview-leak-memory
    
         */
        [webView loadHTMLString:@"" baseURL:nil];
    
        /*
    
         #2: Others claim that UIWebView's will leak if they are loading content
         during dealloc.
    
         Source: http://stackoverflow.com/questions/6124020/uiwebview-leaking
    
         */
        [webView stopLoading];
    
        /*
    
         #3: Apple recommends setting the delegate to nil before deallocation:
         "Important: Before releasing an instance of UIWebView for which you have set
         a delegate, you must first set the UIWebView delegate property to nil before
         disposing of the UIWebView instance. This can be done, for example, in the
         dealloc method where you dispose of the UIWebView."
    
         Source: UIWebViewDelegate class reference
    
         */
        [webView setDelegate:nil];
    
    
        /*
    
         #4: If you're creating multiple child views for any given view, and you're
         trying to deallocate an old child, that child is pointed to by the parent
         view, and won't actually deallocate until that parent view dissapears. This
         call below ensures that you are not creating many child views that will hang
         around until the parent view is deallocated.
         */
    
        [webView removeFromSuperview];
    
        webView = nil;
    }
    

    请试一试,在 viewWillDisappear 中调用这个方法:

    【讨论】:

      猜你喜欢
      • 2012-04-24
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      • 2019-01-11
      • 1970-01-01
      • 2010-12-09
      • 2021-12-17
      相关资源
      最近更新 更多