前幾天由於數據中加載有html語言的數據,關於html語言和UIWebView,有一些糾結,通過幾天的研究,也有了一些本身的簡單的看法。
我有兩個頁面須要加載html語言(注意,這裏面的html不是從json解析出來的一段html語言,而是整個網站,而後用谷歌的開發者工具可接看到網站的源碼),這段html語言顯示的內容包括排版仍是比較好的,因此我想直接把這個網站加載到個人程序上,可是因爲是別的的數據,概覽上面有一段我不想要的數據,滾動視圖的詳情頁面有我不少不想要的數據,因此我就想到了把這段不想要的代碼給刪除掉。因此我想到了兩個辦法(網頁的源碼咱們是沒法直接的刪除的),第一個,我利用UIWebView的js交互的方法,用dom語言把這一段給隱藏掉(例如: [self.webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName(\"m-app-download\")[0].hidden = true;"];),這段代碼只有在UIWebView請求結束的時候使用才比較好,因此在加載的時候會先出現你不想要的那一部分,而後請求加載完成了以後(用的loadrequest請求)纔會隱藏掉,因此仍是達不到預期的效果;第二個辦法,把整個後臺的數據轉換成字符串,而後刪除或者修改我不想要的那一部分(例如:1. NSString * dataString = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",webUrl]] encoding:NSUTF8StringEncoding error:nil]; 2. dataString = [dataString stringByReplacingOccurrencesOfString:@"\"m-app-download\"" withString:@"
」
]; 3. [self.webView loadHTMLString:dataString baseURL:nil];),通過這三部,也能達到預期的效果,可是會存在一個問題,有點卡,暫時先不處理這,最起碼達到了要求。
而後我滿懷欣喜的去處理滾動視圖上的連接,這個地方要比概覽的網站大的多,加載的東西也很是多,我就利用第二種方法去處理它,由於我第二種方法是處理字符串,當我看到這個地方的字符串的時候,由於有很是多得類似的地方,字符串很難去處理,又一次陷入了糾結,因此我想到一個比較懶的方法,我如今視覺上讓上面的我不想要的隱藏(由於這段字符串處理起來比較的簡單),而後下面的我等請求結束後,在用dom給隱藏掉不就好了,而後繼續作,後來成功了。
而後我覺得是大功告成了,但是在測試的時候,我進入滾動頁面詳情的時候,很是極其的卡,後來就思考這是爲何,而後想到了一個緣由,是否是UIWebView的加載的網站過大,再加上UIWebView的內存不能釋放所形成的,而後我開始想這個解決辦法,那不用UIWebView不就好了,而後我就想到了之前看到的一個第三方類(TFHpple)用來過濾html的標籤,來獲取本身想要的那一部分,因此就開始研究TFHpple,後來才知道過濾標籤須要用到XPath語言(一種過濾xml和html的語言)(關於XPath的一些知識
http://www.ruanyifeng.com/blog/2009/07/xpath_path_expressions.html),後來通過一段時間的學習很快的掌握了這一個知識點(例:使用過程:1.導入 #import
「TFHpple.h" #import
「TFHppleElement.h" #import
「XPathQuery.h」 2.添加一個庫,這個庫是:libxml2.2.dylib。而且還須要設置一些路徑參數,不然會一直報錯;這個路徑的設置,在 targets中,在build settings搜索Header Search Paths,將debug和release設置不一樣的值; debug的值設置成:/usr/include/libxml2 release的值設置成:${SDKROOT}/usr/include/libxml2 3. 將html語言轉換成data, NSString *dataString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"
http://breadtrip.com/mobile/destination/topic/2387718792/"] encoding:NSUTF8StringEncoding error:nil];
NSData *htmlData = [dataString dataUsingEncoding:NSUTF8StringEncoding]; 4.書寫XPath過濾語句: NSString *nodeString = @"//section//dl";
NSString *nodeString = @"//p[@class=\"double-line\"]";
NSString * nodeString = @"//dd[a[@class=\"pic\"]]//img"; //全部的圖片
NSString * nodeString = @"//div[@class=\"info\"]//p[@class=\"summary\"][1]"; //得到全部的文字,15段文字
NSString * nodeString = @"//dd[div[@class=\"info\"]]//a[@class=\"pic\"]//img";
NSString * nodeString = @"//header//img
」
;等等
5.得到想要的那個對象: TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *elements = [xpathParser searchWithXPathQuery:nodeString];(注意數組裏面裝得是 TFHppleElement對象, 這樣能夠打印出來NSString * string = ele.attributes[@"src
」
]; NSLog(@"%@",string);))而後接卸終於結束了,得到數據進行簡單的佈局,這樣佈局的時候就不會有UIWebView那麼好看的界面了,很惋惜。
後來開始加載頁面,原本覺得問題已經解決掉了,但是仍是很是的卡,這是爲何呢,接着就思考緣由而後檢查個人代碼,這些方法都有( NSString * dataString = [NSString stringWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",webUrl]] encoding:NSUTF8StringEncoding error:nil];)這段代碼,測試後這段代碼的耗時是很是長的,並且這段代碼是在主線程來加載的因此,會很是的卡,終於找到了緣由,因此就果斷的用GCD開闢一條線程去加載數據
建立一個串行異步線程(串行異步能保證效率,又能控制它在異步線程上的執行順序,因此用這個),而後回到主線程更新UI界面(self.hud是加載時候的蒙版),不出所料,果真很是的快了,各類快。後來想既然這樣那麼UIWebView應該也沒有問題,因此上面的代碼改爲了UIWebView去loadHTMLString,發現依舊很是的快,並且界面的問題也保證了,果斷欣喜。後來我有進行了瘋狂的點擊測試,發現沒有問題,並且很快,可是就在點擊了100屢次左右,系統打印了內存警告的提示,後來一想,這是對的,由於UIWebView建立後的內存不可以釋放,就算你退出了也不能釋放,因此這個地方,當不少次的建立就可能致使內存警告(離着閃退還有一段距離),因此這個地方還得用TFHpple解析(很搓的界面是wufa避免了,我仍是偷懶先用着UIWebVIew吧)。
總結:問題須要多方面的qu考慮,當遇到卡頓的時候,應該首先想到的就是線程的問題,在知足了功能的要求以後,應該還要站在用戶的角度上去思考問題,好比內存問題,體驗問題等等,這個地方走了不少的彎路,可是也學到了不少的知識,因此說是值得的。慢慢的積跬步而後去致千里。
以上內容純屬本身的看法,但願有錯誤你們一塊兒改正。。。