公元前

之前还是学生时代的时候给社团们学弟学妹们介绍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里面的数据,下次进入免去了下载的过 程。

这在三行代码

的方法是全然行不通的。

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

  1. 屏蔽微软的SignalR

    去年采用ASP.NET MVC开发项目,在谷歌浏览器里调试页面的时候,发现项目在不停地请求数据,链接很奇怪: http://localhost:63004/654c2dd725bb4401b8fc0c ...

  2. 冒泡,快排算法之javascript初体验

    引子:javascript实际使用的排序算法在标准中没有定义,可能是冒泡或快排.不用数组原生的 sort() 方法来实现冒泡和快排. Part 1:冒泡排序(Bubble Sort) 原理:临近的两数 ...

  3. 又是一个愚蠢的错误,皆因.xml而起

       论java中的.xml到底有多坑?! 感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各 ...

  4. 理解性能的奥秘——应用程序中慢,SSMS中快(2)——SQL Server如何编译存储过程

    本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(1)--简介 本文介绍SQL Server如何编译存储过程并使用计划缓存 ...

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

    快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...

  6. Java实现快排+小坑+partition的两种思路

    在做一道剑指Offer的题的时候,有道题涉及到快排的思路,一开始就很快根据以前的思路写出了代码,但似乎有些细节不太对劲,自己拿数据试了下果然.然后折腾了下并记录下一些小坑,还有总结下划分方法parti ...

  7. Protobuf有没有比JSON快5倍?用代码来击破pb性能神话

    转 http://www.sohu.com/a/136487507_505779 2017-04-26 07:58 程序设计 /58 /技术 导读:Google 的 Protocol Buffers ...

  8. 美国是一个"愚蠢而落后的国度"--大家千万别去

    看到一篇文章,写的很诙谐风趣,已经被转载无数遍但却不知道原出处.读过之后又值得我们深思.和大家一起分享: 来美国已多时了.我后悔当初的选择.一直都被西方媒体所蒙蔽欺骗,让我错误地以为美国是一个现代化国 ...

  9. 快上车,react 入门拾遗

    最近朋友圈和微博都刷了一波杰伦的回忆杀–说好不哭,想想都9012了,在学习react如火如荼的路上,也不妨停下脚步来总结总结,朝花夕拾一下. 为了便于阐述,我们还是来段小明和禅师的故事吧. 小明在学习 ...

随机推荐

  1. 自定义的圆形ProgressBar

        之前已经详细讲解过自定义控件的使用方式了.这里我单独把定以好的控件列出来. 之前定义的各式各样的ProgressBar http://www.cnblogs.com/tianzhijiexia ...

  2. 自定义各式各样的圆形ProgressBar

         上面三个图分别是 开始时的样子,走进度时候的样子,最后完成的样子 这是我在两个大神的Demo基础上修改后的结果,我们先来看看自定义view是怎么做到的. 1.自己写一个类继承View类,然后 ...

  3. Docker存出载入镜像

    镜像的存出和载入 如果你的生产环境不能连通互联网,而你又希望从互联网上获取镜像.你就需要借助 docker save命令,可以将镜像导出为 tar 文件.使用 docker load 命令,可以将ta ...

  4. 对CAP定理的理解

    CAP定理的常规解释是任何分布式系统只能在一致性(Consitency),可用性(Availability)和分区容忍性(Partition Tolerance)中三选二.这个解释很让人费解,笔者在看 ...

  5. 小游戏:HelloColor

    这是我写的第一个游戏.模仿一款手机游戏"颜色运行"写的.大概花了一天的时间完成,挺简单的. 游戏名:HelloColor,翻译成中文是:你好色 按空格键开始和暂停开始游戏后,界面右 ...

  6. 【转】qt ,使用tcp/ip协议网络传输数据时,字节序转换方法

    网络传输数据是需要保证字节序的正确,才能保证传输数据的准确,网络字节序一般是大端字节序.qt提供了以下两种方法来将本地字节序转换为网络字节序: 方法一,使用qt提供的字节序转换函数 T qFromBi ...

  7. SGU536 Berland Chess

    棋盘上白子只有一个国王  黑子给出 各子遵从国际象棋的走法 黑子不动,白子不能走进黑子的攻击范围以内 问白字能不能吃掉所有的黑子 直接搜索就好了,各子状态用二进制表示 不过每个子被吃之后攻击范围会改变 ...

  8. Windbg命令学习15(bp bm bu bl bc ba断点)

    以下以skinhgy为例,windbg附加运行 1. bp 命令是在某个地址下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction . 对于后者,WinDBG 会 ...

  9. 构建-4 dependencies 依赖管理

    官方文档 Add build dependencies The Gradle build system in Android Studio makes it easy to include exter ...

  10. AngulerJS学习(五)按需动态载入文件

    在此之前我么年首先要先了解几个东西: $q 简单介绍: $q:主要解决的是异步编程的问题,是指描写叙述通过一个承诺行为与对象代表的异步运行的行动结果的交互.可能会也可能不会再不论什么时候完毕. 我们通 ...