UIWebView內存消耗過多解決方法

UIWebView內存消耗過多解決方法

在iOS開發時,使用UIWebView 來加載顯示一個網頁是比較常見的情況. 用 過UIWebView 的人可能知道當應用使用多個UIWebView 來加載網頁時,內存使用增加特別厲害.最近剛好遇到這個問題. 應用普通內存只使用 20~30M的樣子, 當一直打開UIWebView 的時候(我webView加載的是視頻網頁) 最高內存使用達到了 220M. 這個內存使用已經太多了.
在Google, Stackoverflow, 百度啥的都找了,發現UIWebView內存使用過多的問題好多年都沒解決. 無意中找到一篇文章說WKWebView的, WKWebView 是iOS8 以后才可以使用,WKWebView 和UIWebView 差不多都是用于加載一個html 頁面,但是WKWebView 能夠很好的解決UIWebView 內存使用過多的情況. 測試是使用UIWebView 內存使用一般是 180~190M, 當換成 WKWebView 后內存使用一般保持在 25M 左右(我是用iphone 5測試).

本文主要有3 部分內容:

WKWebView的基本使用方法

針對iOS8以前的設備同時使用 WKWebView 和 UIWebView

NSURLConnection 緩存設置及清除

下面是使用**WKWebView 的基本方法:

  1. 加 import :
    #import <WebKit/WebKit.h> `

  2. 基本聲明初始化
    - (void)viewDidLoad {
    [super viewDidLoad];
    WKWebView *test = [[WKWebView alloc]init]; test.frame = CGRectMake(0, 150, 320, 300);
    test.backgroundColor = [UIColor grayColor];
    [self.view addSubview:test];
    NSURLRequest *request = [NSURLRequest requestWithURL: [NSURL URLWithString:@"http://www.baidu.com"]];
    [test loadRequest:request];
    }

(如需同時兼容iOS8 和 iOS8 之前設備請看以下)****以上代碼僅在iOS8以后有效所以,在iOS8之前還是使用UIWebView吧,用于過渡. 附帶說下區分iOS8 和 iOS8 之前分別使用 UIWebView和WKWebView.:

  1. 判斷當前設備系統版本:
    #define IOS8_OR_LATER __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0

  2. 在所有使用到UIWebView的情況下進行判斷(我自己是定義了兩個成員變量,在iOS8之前使用webView, iOS8之后使用wkWebView),如

    - (void)initWebView{   
         if (IOS8_OR_LATER) {     
           if (!_wkWebView) {            
        self.wkWebView = [[WKWebView alloc]initWithFrame:self.view.bounds];               
        self.wkWebView.backgroundColor = [UIColor whiteColor];            
        self.wkWebView.navigationDelegate = self;      
          }      
          [self.view addSubview:_wkWebView];  
          } else {      
          if (!_webView) {       
             self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];         
           self.webView.backgroundColor = [UIColor whiteColor];                       
        _webView.delegate = self;          
          [self.view addSubview:_webView];      
          }      
          [self.view addSubview:_webView];    }
        }
    
  3. 實現兩個 delegate

    @interface BaseWebView ()<UIWebViewDelegate,WKNavigationDelegate>
    
  4. 主要delegate 方法
    // WKNavigationDelegate 頁面開始加載時調用
    - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    [self startLoad];
    }
    // WKNavigationDelegate
    當內容開始返回時調用
    - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    //navigationAction.request.URL.host
    NSLog(@"WKwebView ... didCommitNavigation ..");
    }

        - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {  
          NSURL *requestURL = navigationAction.request.URL;   
            if ([self validateRequestURL:requestURL]) {```
        //允許跳轉        decisionHandler(WKNavigationActionPolicyAllow);  
        } else {        decisionHandler(WKNavigationActionPolicyCancel);  
          }}
        // WKNavigationDelegate 頁面加載完成之后調用
        - (void)webView:(WKWebView *)webView didFinishNavigation:           (WKNavigation *)navigation{    
        [webView evaluateJavaScript:@"document.title" completionHandler:^(id a, NSError *e) {     
           NSLog(@"title is %@",a);        
        NSString *tmpTitle = (NSString *)a;     
           if (tmpTitle.length > 9) {            self.title = [tmpTitle substringToIndex:9];       
             UITabBarItem *item = [self.tabBarController.tabBar.items objectAtIndex:1];                      
     } else {   
      self.title = tmpTitle;         
           UITabBarItem *item = [self.tabBarController.tabBar.items objectAtIndex:1];                    }       
            }];
           [self finishLoad];}
        // WKNavigationDelegate 頁面加載失敗時調用
    - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{    
          NSLog(@"加載失敗!!!!");  
          [self performSelector:@selector(loadFail) withObject:nil afterDelay:4];
        }
    

其它一些基本消除NSURLConnection 的緩存方法:(選用)**

1. 設置緩存大小, AppDelegate 的 didFinishLaunchingWithOptions 方法里:

//內存   
int cacheSizeMemory = 1*1024*1024;
int cacheSizeDisk = 5*1024*1024;              
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
[NSURLCache setSharedURLCache:sharedCache];

2. 消除緩存,在需要的地方加入以下代碼,如退出 WebView 的時候:

 - (void)viewWillDisappear:(BOOL)animated{
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容