iOSUIWebView---快停下啦,你的愚蠢的行为

公元前

之前还是学生时代的时候给社团们学弟学妹们介绍iOS编程的时候,简单的准备了图灵ios培训第一周(使用UIWebView创建简易浏览器)

NSURL *url =[NSURL URLWithString:urlString];

NSLog(urlString);

NSURLRequest *request =[NSURLRequest requestWithURL:url];

[webView loadRequest:request];

运用的就是上面的这样的三行代码搞定一切的网页载入的方法。

公元后

后来在项目中遇到了使用UIWebView控件时,理所当然的愚蠢的

用了里面的方法完毕了Boss的需求,但后期測试的时候,在肾4上

以及用Charles工具模拟慢网速的时候发现这样做的用户体验不太

好,基本的问题就是当该网页内容许多的时候,在2G网络和移

动3G网络的时候,出现载入太慢。出现卡顿的现象。甚至在旧机

器上会出现崩溃的现象。

分析一下原因,主要由下面几种原因:

1.旧的手机CPU性能内存较差。一下占用率太高。(PS:后来

iOS8之后苹果出了新的WebKit框架WKWebKit,性能提升了不

少,建议不须要适配iOS8下面的能够考虑尝试)

2.页面内容较多,数据量庞大,即使是新款手机也扛不住呀(最

典型的应该是天猫商城App的首页啦,下拉了几分钟还没有到达尽

头,一下子载入所有数据。手机肯定扛不住呀)

3. 运用上面那种人人都会的没技术含量的代码是在主线程里面进

行的,数据量大。网速不行,会一值在载入,影响用户进行其它

操作

那如何解决上边的问题呢?

  1. 换手机?别逗了一个肾机依然那么贵,NO Pass
  2. 载入页面的时候做上缓存,甚至分段的展示数据(先仅仅载入一部分数据。随着用户下拉再逐步载入)
  3. 既然操心数据量多造成在主线程调用会卡死,那就想想办法另外开辟线程载入数据。

权衡之后

上边的代码方法是万万行不通的最经常使用的还是想想办法另辟蹊径的开辟新航线:

这里我们能够用到经常使用多线程四种方法中的一种:

NSOperationQueue 操作队列中进行编程

1.创建一个队列并初始化:

static NSOperationQueue *queue;
queue=[[NSOperationQueue alloc]init];

2.创建操作对象并封装要运行的任务

 NSInvocationOperation *op=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoadWeb) object:nil];

将对象加入到队列中

 [queue addOperation:op];

3.开辟一个新的线程,实现运行的任务,获取从server上载入的数据,并存储在NSData中

 -(void)downLoadWeb
    {

NSURL *url=[NSURL URLWithString:@"http://·········.php"];

NSError *error;

NSString *strData=[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];

NSData *data=[strData dataUsingEncoding:NSUTF8StringEncoding];

if (data !=nil) {

    [self performSelectorOnMainThread:@selector(downLoad_completed:) withObject:data waitUntilDone:NO];

}
else
{
    NSLog(@"error when download:%@",error);

}
}

4.推断从server中正确的获得数据后,再返回主线程中进行数据的载入(为啥要返回主线程,由于苹果规定数据载入到控件上必须在主线程上进行,防止多个线程改动控件引发崩溃和莫名其妙的问题)

-(void)downLoad_completed:(NSData *)data
{

NSURL *url=[NSURL URLWithString:@"http://·········.php"];
   NSString *nameType=[self mimeType:url];
NSLog(@"%@",nameType);

[webView loadData:data MIMEType:nameType textEncodingName:@"UTF-8" baseURL:url];
}

上面中用到了UIWebView的

loadData:<#(nonnull NSData *)#> MIMEType:<#(nonnull NSString *)#> textEncodingName:<#(nonnull NSString *)#> baseURL:<#(nonnull NSURL *)#>

//第一个诶參数是一个NSData
//第二个參数是MIMEType
//第三个參数是编码格式
//第四个相对地址。

当中第二參数须要调用一下下面方法,获取指定URL的MIMEType类型

 #pragma mark 获取指定URL的MIMEType类型
- (NSString *)mimeType:(NSURL *)url
{  

NSURLRequest *request = [NSURLRequest requestWithURL:url];  

   //使用同步方法后去MIMEType
NSURLResponse *response = nil;  

[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];  

return response.MIMEType;
} 

这里返回的是text/html

第四个參数是传的URL的地址。当时我尝试着赋值nil后发现网页里面的图片就不能正确的显示出来

好了。介绍好了步骤后反思一下为什么这么做比較好的用户体验

1.首先我们运用了多线程载入数据。不影响用户操作其它数据

我还有益调皮的在downLoadWeb中加上下面的代码:

for (int i=1; i<100000000; i++) {
    NSLog(@"我卡到你了吗?");
}

測试结果全然不影响用户操作其它地方。要是按原始的三行代

码搞定UIWebView就会出现一直卡的悲催体验。

2.我们先在子线程中把数据载入到NSData中,再 通过loadData:函

数进行载入,相当于进行了本地数据的读取操作。本地读取的速

度是远远大于网络获取的。

3.对于网页数据基本保持不变的,我们全然能够 用数据库存储

NSData里面的数据,下次进入免去了下载的过 程。

这在三行代码

的方法是全然行不通的。

时间: 2024-12-19 12:46:22

iOSUIWebView---快停下啦,你的愚蠢的行为的相关文章

linux 进程基础(四)

本小结主要对linux进程的调度部分进行学习总结. linux是个支持多任务的操作系统,因此才会涉及到进程的调度,调度的目的是为了让多个进程并 存.在当前CPU是多核(单核的CPU系统中面对多任务时也涉及到进程的调度)的情况下,CPU可以高效的 对处于可执行状态的进行调度处理.以提高系统的业务处理能力. 进程的调度其实质就是CPU对处于可执行状态的进程进行处理的过程,这要求linux进程调度器在设 计上可以处理几个甚至是相互矛盾的目标: A.高效性:高效意味着在相同的时间下要完成更多的任务: B

更快学习 JS 的 6 个简单思维技巧

当人们尝试学习 JavaScript , 或者其他编程技术的时候,常常会遇到同样的挑战: 有些概念容易混淆,特别是当你学习过其他语言的时候. 很难找到学习的时间(有时候是动力). 一旦当你理解了一些东西的时候,却很容易再一次忘记. 可以使用的工具甚多且经常变化,所以不知道从哪里开始入手. 幸运的是,这些挑战最终都可以被战胜.在这篇文章里,我将介绍 6 个思维技巧来帮你更快的学习 JavaScript ,让你成为一个更快乐更多产的程序员. 1.不要让将来的决定阻止你进步 对于很多学习 JavaSc

Google的量子计算之梦:比传统计算机快上1亿倍?

Google的量子计算之梦:比传统计算机快上1亿倍? 本文来自technologyreview,作者 Tom Simonite ,机器之心编译出品,参与:salmoner,薛矽,汪汪,微胖. 近日,谷歌宣布他们的量子计算机比传统计算机快上1亿倍,有人欢呼雀跃,有人提出质疑.让我们来看看背后的故事吧,看看物理学家John Martinis 如何帮谷歌实现炙手可热的量子计算之梦.他或许正手握着量子计算的圣杯,本文选自麻省理工科技评论. Martini团队追寻的神奇计算机 John Martinis用

“脑子快”的程序员更优秀吗?

转自:http://www.iteye.com/news/30801 今天Hacker News上的一篇文章<为什么想得慢的人能赢>引起了广泛的讨论. 网友Scott Burson在文章后评论说:“之前,我雇佣了一位TopCoder冠军,原本预计他编码飞快,但实际上他是最小心细致的人,不过大家渐渐发现,两年内,他提交的代码从来没有bug,从来没有.” 为什么看起来思考缓慢的人却能胜出呢? 作者表示,所谓的反应慢比反应快需要更多的自律.相比之下,反应快就会更加不准确,而缓慢的思考就像乌龟,慢却稳

打车大战即将落幕:滴滴68.1%甩开快的

手机打车市场竞争并未因补贴大战的结束而就此平息,在过去一段时间,滴滴和快的这两家死对头仍然在不断的尝试各种策略去提升综合竞争力,不过,由于二者的实力并不平均,因此市场表现也大相径庭.6月18日,互联网数据研究机构发布了<2014年5月中国打车软件市场分析报告>,报告显示,滴滴打车市场份额达到68.1%,稳居市场第一,且相较于第一季度的60.2%上升了7.9%.快的打车则获得30.2%的市场份额,位居第二. 数据上看,滴滴的优势仍在继续扩大,市场份额为快的的两倍还多,一般说来,如果第二名和第一名

17暑假高一假期作文素材《最愚蠢的一代》

       尽管工作很忙,但"偷得浮生半日闲",只要有时间,我就同家人在一起.我爱好挺多,最大的爱好是读书,读书已成为我的一种生活方式.  --2013年3月19日 习大大接受金砖国家媒体联合采访 我们正进入另一个黑暗和无知的时代 美国埃默里大学的英语教授马克·鲍尔莱因写了<最愚蠢的一代>,就得罪了8700万美国年轻人. 在书中,他提出一个让美国教育界困惑不已的问题:在整个人类历史上,知识从来没有像现在这样普及过:图书馆.博物馆.大学.历史频道.维基百科.<华尔街

(转)最快速度找到内存泄漏

最快速度找到内存泄漏 许式伟 2006年11月某日 内存管理是C++程序员的痛.我的<内存管理变革>系列就是试图讨论更为有效的内存管理方式,以杜绝(或减少)内存泄漏,减轻C++程序员的负担.由于工作忙的缘故,这个系列目前未完,暂停. 这篇短文我想换个方式,讨论一下如何以最快的速度找到内存泄漏. 1.确认是否存在内存泄漏 我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏.例如: class CMyApp : public CWinApp { public: BO

快速排序—三路快排 vs 双基准

快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Java 7发布两年后)快速排序实现的Arrays.sort被双基准(dual-pivot)排序的一种变体取代了.这篇文章不仅展示了为什么这个变化如此优秀,而且让我们看到Jon Bentley和Joshua Bloch的谦逊. 我当时做了什么? 与所有人一样,我想实现这个算法并且对一千万个数值排序(随机

最快速度找到内存泄漏[转载]

转载链接:http://blog.csdn.net/eric_jo/article/details/4264442 内存管理是C++程序员的痛.我的<内存管理变革系列>就是试图讨论更为有效的内存管理方式,以杜绝(或减少)内存泄漏,减轻C++程序员的负担. 这篇短文我想换个方式,讨论一下如何以最快的速度找到内存泄漏. 确认是否存在内存泄漏 我们知道,MFC程序如果检测到存在内存泄漏,退出程序的时候会在调试窗口提醒内存泄漏.例如: class CMyApp : public CWinApp { p