前几天因为数据中加载有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考虑,当遇到卡顿的时候,应该首先想到的就是线程的问题,在满足了功能的要求之后,应该还要站在用户的角度上去思考问题,比如内存问题,体验问题等等,这个地方走了很多的弯路,但是也学到了很多的知识,所以说是值得的。慢慢的积跬步然后去致千里。
 
以上内容纯属自己的见解,希望有错误大家一起改正。。。
 
 
     

关于学习是UIWebView的一些思考的更多相关文章

  1. ios网络学习------4 UIWebView的加载本地数据的三种方式

    ios网络学习------4 UIWebView的加载本地数据的三种方式 分类: IOS2014-06-27 12:56 959人阅读 评论(0) 收藏 举报 UIWebView是IOS内置的浏览器, ...

  2. Spark的Straggler深入学习(2):思考Block和Partition的划分问题——以论文为参考

    一.partition的划分问题 如何划分partition对block数据的收集有很大影响.如果需要根据block来加速task的执行,partition应该满足什么条件? 参考思路1:range ...

  3. linux学习的哲学层面的思考-架构

    参考:http://blog.chinaunix.net/uid-26119273-id-3356414.html 学习Linux,准备做产品的话,不要把Linux当成了终极目标(当然,这是对应用而言 ...

  4. IOS开发-UI学习-UIWebView,简单浏览器的制作

    制作一个简单的浏览器,包含网址输入框,Search按钮,前进.回退按钮,UIWebView就这几个简单的控件. UITextField:用来输入网址: UIbuttom:实现前进,后退,搜索等功能: ...

  5. Angular 学习笔记 (组件沟通的思考)

    组件指令间经常需要沟通 我们知道的方式有 input output service inject viewchild contentchild templateRef template variabl ...

  6. ios学习之UIWebView网页视图调整

    //先来一个可行的小Demo程序:结合searchBar的google搜索 #import <UIKit/UIKit.h> @interface ViewController : UIVi ...

  7. ios学习之UIWebView网页视图

    转载于爱德凡的百度空间,地址:http://hi.baidu.com/aidfan/item/34a720866b33cbcdef083d37 UIWebView 使用详解 一.UIWebView加载 ...

  8. Java学习笔记--关于面向对象的思考

    1.不可改变的类生成对象以及变量的范围 2. 关键词this的使用 3.用类抽象的思想制作软件 4.通过关系模型建立类 5.使用面向对象的范例来设计程序,遵循类设计指导. 已经学习了:怎么定义类已经创 ...

  9. JMeter学习笔记21-如何添加思考时间

    本文来介绍,JMeter如何插入思考时间.前面介绍过一个真实的性能测试场景,是需要加入思考时间,来模拟真实用户行为.本文就来介绍,如何在三个请求之间添加思考时间. 1. 在Test Plan下新建一个 ...

随机推荐

  1. 【Selenium2+Python】常用操作

    Webdriver中比较常用的操作元素的方法: clear()    清除输入框的默认内容 send_keys("xxx")    在一个输入框里输入xx内容 ——如果输入中文,则 ...

  2. HDU 1538

    http://acm.hdu.edu.cn/showproblem.php?pid=1538 经典经济学问题,海盗分金 分析http://www.guokr.com/article/41423/ #i ...

  3. php用压栈的方式,循环遍历无限级别的数组(非递归方法)

    php用压栈的方式,循环遍历无限级别的数组(非递归方法) 好久不写非递归遍历无限级分类...瞎猫碰到死老鼠,发刚才写的1段代码,压栈的方式遍历php无限分类的数组... php压栈的方式遍历无限级别数 ...

  4. 十分钟了解分布式计算:GraphLab

    GraphLab是一个面向大规模机器学习/图计算的分布式内存计算框架,由CMU在2009年开始的一个C++项目,这里的内容是基于论文 Low, Yucheng, et al. "Distri ...

  5. Angularjs中的promise

    promise 是一种用异步方式处理值的方法,promise是对象,代表了一个函数最终可能的返回值或抛出的异常.在与远程对象打交道非常有用,可以把它们看成一个远程对象的代理. 要在Angular中创建 ...

  6. IOS 不兼容 伪类active

    添加空的 事件ontouchstart 例 <body ontouchstart>

  7. PHP聊天室框架

    内容和教程可以在这个网址查看 http://www.workerman.net/workerman-chat

  8. C++宽窄字符串转换

    首先,贴出我给出的解决方案: http://files.cnblogs.com/xuejianhui/utils.rar   再则,贴出网上最常见的例子: #include <string> ...

  9. 我的STL之旅 MyList

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> // ...

  10. IOS开发-CAlayer-锚点小结

    CAlayer层的属性:anchorPoint(锚点)   CAlayer *view; 1.决定着CALayer上的哪个点会在position属性所指的位置(设置以后旋转动画,就是以锚点为中心旋转) ...