1.Head请求:不获取响应体(返回的响应没有响应体 )只获取响应头
输出参数:传栈地址
2.null 空地址 空指针((void*)0) 0地址
nil 空对象((void*)0)
本质相同 都是0地址 混用不会出现问题 但是表达的语义不同
NSNull :对象本身不为空 表达“空”的概念 eg:NSArray * array = @[[NSNUll null]]
3.下载文件用sendAsync问题:内存占用过多 内存泄漏 崩溃
原因:文件数据都加载到内存中
创建NSURLConnection/*请求 代理*/
代理:每次获得数据就调用/*connection;本次得到的数据长度;总共得到的文件长度;文件的总长度*/
4.NSURLConnectionDownloadDelegate能下载 但是不能保存文件数据 :因为没有使用Newsstand kit 框架
dataDelegate 保存数据的时候不能用NSData进行累加 内存溢出
5.didReceiveData本次从网上获取数据 获得二进制数据data
计算进度:文件总长度 (//数据长度的累加) 当前已经得到的数据长度
6.保存文件到cache connectionDidFinishLoading
此时文件的所有数据都加载到内存中 导致内存溢出
保存数据 :NSFileHandle:写入沙盒 指定文件写入的路径 如果文件路径所对应的文件不存在 该对象为空
//创建文件 //文件已经存在 找到文件的末尾 目的是在末尾处继续写新的数据 //写入数据 //关闭filehandle
7.NSStream输出流:NSOutputStream/*文件保存的路径;是否追加数据*/
//打开输出流 //把数据流入文件//关闭输出流
问题:叠加下载
解决:判断文件是否存在(在didReciveResponse中)//NSFileManager 文件管理 存在就删除
8.断点续传:
(1)//获取服务器文件的总长度:目的是用来与本地文件的长度对比进行判断
-(void)getServerFileInfo:(NSURL*)url{
//head请求
NSMutableURLRequest = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @“head”;
NSURLResponse * response;
//得到响应头 文件的总长度 文件名
//拼接文件保存的路径
}
(2)判断本地文件是否存在 返回从哪里开始下载
//NSFileManager 文件管理 存在就删除
if(![fileMan fileExistsAtPath:self.fileSavePath]){
return 0;
}else{
//文件存在
//获取本地文件大小
NSDictionary * attrs = [fileMan attributesOfItemAtPath:self.fileSavePath error:NULL];
}
不存在:从0开始下载 存在:得到本地文件的长度作比较:a.本地文件的长度==服务器文件的长度 下载完成
b.本地文件的长度 < 服务器文件的长度 没有下载完成 从文件的末尾接着下载
c.本地文件的长度>服务器文件的长度 文件有问题 删除文件 从0开始下载
(3)从服务器的中间节点开始下载 告诉服务器从哪个地方开始下载
/*语法:
Range:bytes = x- 从x处下载到文件末尾
Range:bytes = -y 从头下载到y处
Range:bytes = x - y 从x下载到y处
*/
9.//创建NSURLConnection
//子线程的消息循环默认不运行 NSURLConnection依赖消息循环 手动开启子线程的消息循环
//为了方便vc在文件下载完成的时候进行ui操作 在主线程添加队列 线程间通信
10.当多次调用下载方法的时候 每点击一次 就会开启下载 点击多次就会开启多个下载 进度progress都是通过progressBlock回调回vc
11.//管理downloader 判断是否已经开启了下载 如果已经开启了 就return
//经理需要提供给vc下载和暂停操作 通过经理的统一指挥 调用员工downloader
//单例+(instance)sharedManager
12.下载:
//拦截
//调用vc传过来的block代码
//删除操作缓存
//操作缓存:目的是用来存储正在运行的下载操作
//把下载操作加入到操作缓存中
13.暂停:从操作缓存中取到对应的操作
//取消
//删除缓存操作
14.用NSOperation改写 main方法 需要我们自己指定 将来通过操作队列的调度 会在一个子线程运行