UIWebView не сразу останавливается

Я пробовал все эти ( один, два, три, четыре), но после того, как я вернусь с экрана веб-просмотра на предыдущий viewController, он зависает примерно на 2 секунды (иногда больше). В viewWillAppear нет ничего, что вызовет замораживание.

Здесь viewWillDisappear контроллера веб-представления:

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

Первый viewController:

-(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, не будет наблюдаться замедление.

Ответ 1

Я делаю следующее, что похоже на то, что предлагает @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, так как это останавливает запрос на загрузку. Возможно, это не так с решением Муннал?

Ответ 2

Попробуйте это в viewWillDisappear:

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

Ответ 3

Используете ли вы NSURLProtocol для перехвата веб-запросов из UIWebView? Следующий ответ написан на этом предположении.

Загрузка веб-страницы включает отправку запросов на несколько ресурсов (изображения, видео, html, javascript). Каждый из этих ресурсов имеет URL-адрес, который будет перехвачен NSURLProtocol

Теперь, если вы закроете webView перед загрузкой всех ресурсов, NSURLProtocol иногда принимает отменить все открытые запросы на ресурсы, которые он перехватывает, и в этом процессе замораживание вашего приложения.

Вы отмените регистрацию из NSURLProtocol перед выходом из WebView. Итак,

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

должен исправить проблему с замораживанием

PS: Иногда у вас может быть NSURLProtocol, определенный для всего приложения, и в этом случае я думаю, что лучше выделить NSURLProtocol для UIwebView из остальной части приложения. Я не знаю много о вашем проекте, чтобы я мог прокомментировать, если это возможный вариант для вас.

Ответ 4

Я думаю, что веб-просмотр может все еще обрабатываться в фоновом режиме. И я убедился, что совершенно неудобно выпускать UIWebView полностью. Возможно, вам захочется взглянуть в Профилировщик: вверх и закрыть WebView ViewController несколько раз, буфер должен неуклонно увеличиваться.

Вот почему я подошел, чтобы объединить несколько подходов решения от, чтобы окончательно и полностью удалить все хранилище из веб-представления, а также не остановить его.

Очень важно, чтобы веб-просмотр был равен нулю, чтобы действительно освободить память, в прежние времена у нас был метод 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/info/648396/does-uiwebview-leak-memory

     */
    [webView loadHTMLString:@"" baseURL:nil];

    /*

     #2: Others claim that UIWebView will leak if they are loading content
     during dealloc.

     Source: http://stackoverflow.com/info/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: