GCD和NSOperation多线程技术

 
第一讲  GCD
 
GCD会管理多线程的生命周期
 
GCD底层线程池,队列跟底层线程池之间的交互,底层线程池对线程进行了复用,使用效率要高
 
GCD跟NSThread对比
 
 
  1. 开不开线程,和执行任务的函数有关
- 同步不开
- 异步开
  1. (异步)开几条线程,和队列有关
- 串行队列最多开一条
- 并发队列开N条,具体条数由GCD决定!
 
 
主队列:
 
主队列同步会死锁:
 
注意主队列同步也能够不死锁,具体状况具体对待
 
主队列异步: 不会开启线程,在主线程中执行,可是主队列中的任务须要等待主线程中任务执行完毕以后才能执行
 
barrier阻塞:
会先循环执行完下载完成(全部异步执行完以后再执行barrier的block中代码),同一线程中顺序执行
注意:dispatch_barrier_async 必须使用自定义队列,不然执行效果和全局队列一致
 
dispatch_once 只执行一次的代码,注意单例中的static可以保证在block中局部变量能够记录保存在静态区,不会被销毁
 
dispatch_once是同步的,是线程安全的, dispatch_once内部也有一把锁,这把锁的性能很高
 
 
dispatch_group  调度组  dispatch_group_notify 异步的
 
 
dispatch_after 延迟操做- 异步执行的   所以在dispatch_after的block中执行的任务是在子线程中执行
 
 
第二讲  NSOperation
 
iOS8以后,GCD底层的线程池特别慷慨,只要要就给,能够开不少条线程
 
NSOperation是iOS2.0推出的,GCD是iOS4.0推出的
ARC是Xcode4.2推出的
 
 
NSInvocationOperation和NSBlockOperation的使用(都是异步并发执行的)
 
 
线程间通信:
 
NSOperation和GCD的对比:
 
NSOperation设置最大并发数  setMaxConcurrentOperationCount
 
暂停继续(队列的挂起状态),挂起的是队列,不会影响正在执行的操做
 
 
 
取消,暂停和继续
 
依赖关系
 
异步下载图片
在异步下载图片的时候的问题及解决:
 
 
当异步下载图片以后,因为blockOperation是异步下载的,当返回cell的时候image还未下载下来,因此因为cell的imageView懒加载,并未显示图片,当点击或者上下滚动才显示
 
解决办法:占位图片提早设置imageView,固定imageView的大小
 
可是此时又有问题,占位图片太大,下载图片小,因此一开始显示占位图片大点击cell以后显示小的下载图片
 
解决办法:自定义cell,设置好imageView的大小,能够完整显示占位图片和下载图片
 
然而还有问题,此时图片每次滚动都会下载,而且当网速不一样会致使图片错位,缘由:好比第一个cell的图片下载很快,第九个以后就很慢,当第一个cell进入缓存池以后,第十个cell会进行cell复用,此时cell的图片下载很慢,图片还未下载完,当在往上滚动的时候,第一个cell会复用第十个 cell,因为第一个cell图片下载快,因此显示以后过几秒会再下载显示第十个cell未下载完的图片,从而发生图片错位的现象。
 
解决办法:利用MVC模式,在模型中定义图片属性,将图像异步保存在模型中,并刷新当前行调用数据源方法,在cell中判断模型是否有图片,显示模型中存储的图像。这样同时解决了不断从网络下载的问题
 
操做缓冲池:
 
为何须要操做缓冲池?由于在下载网络图片的时候,当网络很慢,而用户快速滑动,好比第一个cell的图片没有下载完,因而会在建立一个操做添加到队列中,这样会形成资源的浪费
 
 
下载结束,清除操做缓冲
 
图像缓冲池的引入
 
因为模型内保存图片跟模型绑定的很紧,当接收到内存警告的时候很差释放,因此须要引入图像缓冲池,相似于操做缓冲池,用url做为key用字典缓冲
 
layoutsubviews方法的调用
 
 
内存警告清理缓冲池
 
实现沙盒缓存见SDWebImage
相关文章
相关标签/搜索