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. 运用上面那种人人都会的没技术含量的代码是在主线程里面进
行的,数据量大。网速不行,会一值在载入,影响用户进行其它
操作
那如何解决上边的问题呢?
换手机?别逗了一个肾机依然那么贵,NO Pass
载入页面的时候做上缓存,甚至分段的展示数据(先仅仅载入一部分数据。随着用户下拉再逐步载入)
既然操心数据量多造成在主线程调用会卡死,那就想想办法另外开辟线程载入数据。
权衡之后
上边的代码方法是万万行不通的最经常使用的还是想想办法另辟蹊径的开辟新航线:
这里我们能够用到经常使用多线程四种方法中的一种:
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里面的数据,下次进入免去了下载的过 程。
这在三行代码
的方法是全然行不通的。
iOSUIWebView---快停下啦,你的愚蠢的行为的更多相关文章
- 屏蔽微软的SignalR
去年采用ASP.NET MVC开发项目,在谷歌浏览器里调试页面的时候,发现项目在不停地请求数据,链接很奇怪: http://localhost:63004/654c2dd725bb4401b8fc0c ...
- 冒泡,快排算法之javascript初体验
引子:javascript实际使用的排序算法在标准中没有定义,可能是冒泡或快排.不用数组原生的 sort() 方法来实现冒泡和快排. Part 1:冒泡排序(Bubble Sort) 原理:临近的两数 ...
- 又是一个愚蠢的错误,皆因.xml而起
论java中的.xml到底有多坑?! 感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各 ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(2)——SQL Server如何编译存储过程
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(1)--简介 本文介绍SQL Server如何编译存储过程并使用计划缓存 ...
- 快速排序—三路快排 vs 双基准
快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...
- Java实现快排+小坑+partition的两种思路
在做一道剑指Offer的题的时候,有道题涉及到快排的思路,一开始就很快根据以前的思路写出了代码,但似乎有些细节不太对劲,自己拿数据试了下果然.然后折腾了下并记录下一些小坑,还有总结下划分方法parti ...
- Protobuf有没有比JSON快5倍?用代码来击破pb性能神话
转 http://www.sohu.com/a/136487507_505779 2017-04-26 07:58 程序设计 /58 /技术 导读:Google 的 Protocol Buffers ...
- 美国是一个"愚蠢而落后的国度"--大家千万别去
看到一篇文章,写的很诙谐风趣,已经被转载无数遍但却不知道原出处.读过之后又值得我们深思.和大家一起分享: 来美国已多时了.我后悔当初的选择.一直都被西方媒体所蒙蔽欺骗,让我错误地以为美国是一个现代化国 ...
- 快上车,react 入门拾遗
最近朋友圈和微博都刷了一波杰伦的回忆杀–说好不哭,想想都9012了,在学习react如火如荼的路上,也不妨停下脚步来总结总结,朝花夕拾一下. 为了便于阐述,我们还是来段小明和禅师的故事吧. 小明在学习 ...
随机推荐
- docker 查看容器的网络连接
#! /bin/bash echo $1 PID=$(docker inspect -f '{{.State.Pid}}' $1) nsenter -t $PID -n netstat |grep E ...
- Android避免过度绘制之道
如果一个布局十分复杂,那么就需要来排查是否出现了过度绘制,如果出现了,那么很可能会造成刷新率下降,造成卡顿的现象.那么什么是过度绘制呢?过度绘制就是在同一个区域中叠加了多个控件.这就像小时候我们画画, ...
- 简单绕过Chrome密码查看逻辑,查看浏览器已保存的密码
简单绕过Chrome密码查看逻辑,查看浏览器已保存的密码 利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查 ...
- Petri网
Petri网是一种适合于系统描述和分析的数学模型,主要描述异步和并发关系.(或者Petri网是对离散并行系统的数学表示,适用于描述异步的,并发的计算机系统模型.) Petri网模型自然,直观,简单易懂 ...
- 转:PHP高效率写法(详解原因)
FROM : http://my.oschina.net/No5stranger/blog/157585#OSC_h3_1 1.尽量静态化: 如果一个方法能被静态,那就声明它为静态的,速度可提高1/4 ...
- [转]RSYNC 参数中文详解
FROM : http://www.qiansw.com/rsync-cn.html rsync是一款好用的*nux文件同步工具.下面是其参数的中文解释. Rsync 参数选项说明 -v, --ver ...
- 利用ASP.NET运行数据库的安装脚本
在启明星的演示站点里,经常有用户修改演示密码,导致别的用户无法访问. 为此,在登陆页面,增加了一个“初始化数据库”功能,这样,即使用户修改了密码,别的访问者,只要重置数据库,就可以很容易再次进入. 首 ...
- spring mvc 返回乱码SpringMVC使用@ResponseBody注解返回中文字符串乱码的问题
原文地址:https://www.cnblogs.com/fzj16888/p/5923232.html 先说一下我的经历,以及解决问题的而过程. 在使用SpringMVC的时候,最开始的时候在配置文 ...
- 【ContestHunter】【弱省胡策】【Round8】
平衡树维护凸壳/三角函数+递推+线段树 官方题解:http://pan.baidu.com/s/1sjQbY8H 洛阳城里春光好 题目大意:(其实出题人已经写的很简短了……直接copy的-_-.sor ...
- Android studio 编译失败Error:Could not read entry ':app:processDebugManifest' from cache taskArtifacts.b
Android studio 编译失败 Error:Could not read entry ':app:processDebugManifest' from cache taskArtifacts. ...