iOS开发 - 第04篇 - 网络 - 01 - NSOperation & 网络基础

来源:互联网 发布:小型机房网络拓扑 编辑:程序博客网 时间:2024/04/27 14:32

实现:Cell图片下载程序


源代码下载地址:点击打开链接


1、Cell图片下载程序


1.1 界面




1.2 基本思路


1> Storyboard中添加导航控制器,根控制器为UITableViewController

2> 新建HMAppsViewController,关联

3> 导入app.plist,新建HMApp,提供类方法,利用KVC,字典转模型

4>HMAPPViewController中懒加载模型数组

5> 实现ViewController数据源方法,设置Cell的textLabel和detailTextLabel,并测试

6> 图片下载问题


1.3 Cell图片下载思路 --- 重要


1> 若直接在设置Cell明细的代理方法(主线程)中,下载图片,设置每个Cell图片




1dataWithContentsOfURL:从网络上下载图片,耗时,而且放在主线程中,会造成主线程阻塞,导致拖动变卡(同时网速慢,在下载图片的同时不能拖动界面)

2:设置Cell明细的代理方法,调用频率非常高(一滚动只要出现新的Cell就会调用),上下滚时会导致重复下载,浪费流量


2> 使用NSOperation作为下载线程,且系统会管理下载的线程数

3> 懒加载一个NSOperationQueue,用来存放所有下载操作的队列




1:由于异步执行,很有可能图片还没有下载完,这个Cell就已经返回,还是会导致图片没有显示,来回滚动后可能会显示

注2:应保证图片下载完,设置了Cell以后再返回Cell


4> 首先解决重复下载问题

保证:1张图片只下载1次

即:每一个url对应的Operation只需要一个,一个Operation代表一个下载操作,一对一的对应关系,使用字典!!!

1. 懒加载一个NSMutableDictionary,用于存放所有的下载操作(url是key,Operation对象是value)

2. 在Cell明细方法中,首先判断对应key的Operation是否存在,若不存在则创建对应的Operation,开启下载线程,并将Operation添加到字典中




注:由于是异步执行,添加到队列后,又将Operation添加到字典中,此时用户如果又来回滚动的话,即使下载还没有完成,也不会再去创建新的Operation


5> 此时又会出现两个问题:

1. 存放操作的字典operations会越来越大

2. 如果下载失败,一旦出现一次,该图片就无法再重新下载,因为这个图片url对应的Operation一直存在字典中

解决办法:

1. 下载完后,将操作Operation从字典中移除

2. 此时又导致之前的问题,又会重新下载

3. 因此,再添加一个字典images(懒加载),存放已经下载完的UIImage,可以保证以后需要的时候直接从内存中取,不用再下载

4. Cell明细方法中,应该首先判断images字典中是否已经存在下载好的图片,若无,再去下载,同时再根据operations字典保证不要重复下载

5. 此时若下载失败,images字典中不存在对应的UIImage图片,而且对应的Operation已经移除,可以重新下载






注:字典不能放nil,因此万一图片下载失败

self.images[app.icon]= image;会导致程序崩溃

需加判断

if (image) {

self.images[app.icon]= image;

}


6> 缓存池可重用问题




注:0123是已经下载完的图片,当用户向上拖动时,0被放入缓存池中,此时4进入界面,会从缓存池中加载可重用Cell-0,由于4还没有下载,若4来不及下载完成,不能及时设置Cell-4图片会造成:0的图片显示在4的位置!!!等到4的图片下载完成,再设置回4对应的图片

解决办法:

使用占位图片,在图片未下载完成的时候使用占位图片盖住,代表正在下载,下载完成后设置为相应图片,且下次会直接使用下载好的图片




7> 图片显示错乱问题




还是Cell的循环利用导致,原因如下:




一开始0对应的图片在下载中,用户拖动后,将0放到了缓存池中,4出现的时候,从缓存池中取出了0放到了4的位置,并发送请求下载4对应的图片,此时一开始0对应的图片刚好下载完成,会到主线程中设置0对应Cell的图片,此时由于Cell-0Cell-4对应同一个地址,就会将0的图片设置到4的位置,造成显示错乱,等到4对应图片又下载完成后,再重新设置回4


解决办法:不能直接设置Cell图片,应该重新刷新表格,此时又会调用Cell明细方法,而此时已经有对应的正确图片




此时,基本完成Cell图片下载,保证指下载一次,且以后每次都从缓存中取出图片来显示,拖动tableView也不会卡!


8> 添加内存警告处理

9> 添加开始滚动和滚动结束的队列处理

10> 抽取下载代码

11> 整体思路




12> block循环引用问题

注1:block会对里面的对象进行强引用

注2:此时由于block和self(HMAppsViewController)循环引用,都不能释放




解决办法:block内部使用弱指针


13> 整体代码








1.4 沙盒缓存




1> 将图片存入沙盒




2> 从沙盒中取出图片




2、自定义Operation




将操作中需要执行的操作封装到一个自定义Operation中,如上述Cell图片下载程序中的下载操作

1:一旦将一个操作添加到队列当中,其实内部会调用这个操作的main方法

2:下载完应该通知控制器去刷新表格,使用代理








3、SDWebImage --- 重要




以Cell图片下载程序为例:

1> #import"UIImageView+WebCache.h"

2> 在Cell明细方法中调用方法即可,实现上述图片下载所有操作




3> 其他常用用法




4>SDWebImage内存处理

注:SDWebImage通常属于整个项目,不属于某个控制器(很多控制器都需要使用这个框架),因此需要在整个项目(appDelegate)有内存警告的时候进行内存处理(#import "SDWebImageManager.h")




4、小结


注:SDWebImage缓存时长默认一周




5、网络基础


5.1 简单说明


在移动互联网时代,移动应用的特征有:几乎所有应用都需要用到网络,比如QQ、微博、网易新闻、优酷、百度地图;只有通过网络跟外界进行数据交互、数据更新,应用才能保持新鲜、活力;如果没有了网络,也就缺少了数据变化,无论外观多么华丽,终将变成一潭死水

移动网络应用 = 良好的UI + 良好的用户体验 + 实时更新的数据

新闻:网易新闻、新浪新闻、搜狐新闻、腾讯新闻

视频:优酷、百度视频、搜狐视频、爱奇艺视频

音乐:QQ音乐、百度音乐、酷狗音乐、酷我音乐

LBS:百度地图、高德地图、大众点评、墨迹天气、滴滴打车

电商:淘宝、京东商城、天猫、蘑菇街、凡客诚品、美丽说

社交:QQ、微信、微博、陌陌、比邻


为什么要学习网络编程

网络编程是一种实时更新应用数据的常用手段

网络编程是开发优秀网络应用的前提和基础


5.2 基本概念


在网络编程中,有几个必须掌握的基本概念

客户端(Client):移动应用(iOSandroid等应用)

服务器(Server):为客户端提供服务、提供数据、提供资源的机器

请求(Request):客户端向服务器索取数据的一种行为

响应(Response):服务器对客户端的请求做出的反应,一般指返回数据给客户端

作为移动开发工程师,主要的精力都是放在前端开发




5.3 服务器


1> 服务器分类




2> 本地服务器选择




3> 搭建本地服务器


参考博客:点击打开链接


4> 本地服务器的主机地址




6、URL




注:URL中常见的协议

1> HTTP

超文本传输协议,访问的是远程的网络资源,格式是http://

http协议是在网络开发中最常用的协议

2> file

访问的是本地计算机上的资源,格式是file://(不用加主机地址)

3> mailto

访问的是电子邮件地址,格式是mailto:

4> FTP

访问的是共享主机的文件资源,格式是ftp://


7、HTTP协议


1> HTTP协议(全称是Hypertext Transfer Protocol,超文本传输协议)简介:不管是移动客户端还是PC端,访问远程的网络资源经常使用HTTP协议(访问百度主页:http://www.baidu.com)




2>HTTP协议特点

1. 简单快速  因为HTTP协议简单,所以HTTP服务器的程序规模小,因而通信速度很快

2. 灵活  HTTP允许传输任意类型的数据

3. HTTP 0.9和1.0使用非持续连接,限制每次连接只处理一个请求,服务器对客户端的请求做出响应后,马上断开连接,这种方式可以节省传输时间


3> HTTP的通信过程

要想使用HTTP协议向服务器索取数据,得先了解HTTP通信的完整过程,完整的http通信可以分为2大步骤

1. 请求:客户端向服务器索要数据

2. 响应:服务器返回客户端相应的数据


4> iOS中发送HTTP请求的方案




8、NSURLConnection






9、模拟登录界面






0 0