模块化
分层
解耦
降低代码重合度
首先图片缓存框架需要有一个管理者Manager,用于协调框架内部的各个模块,一个负责内存管理的模块,一个负责磁盘处理的模块,本地没有图片我们需要支持网络下载图片模块,就构成了图片缓存基本框架,如果图片是被压缩的或者是在内存中保存的图片需要解码之后的图片格式,所以需要配置解码相关的管理者CodeManager,需要一个负责图片解码模块和一个负责图片压缩/解压缩模块。
以图片URL的单向Hash值作为图片访问的Key来存储到对应的图片框架当中。
我们根据Key来获取一张图片,首先需要到内存模块当中进行查找,如果内存模块命中了就结束查找过程,把找到的图片返回给调用方,如果内存没有命中,需要进行磁盘查找,如果命中返回结果,如果没有命中需要进行图片的网络下载。
借鉴系统多级缓存思想,引入内存这一模块
1:10kb以下的图片在日常开发场景中使用比较多,在内存空间当中开辟50个空间来缓存对应的图片。这样我们就能知道10kb以下的图片最终在内存当中占有的容量是多少。
2:大于10kb小于100kb的图片,这样的图片使用的比较少,就可以开辟20个空间来缓存对应图片。
3:大于100kb以上的图片,这样的图片使用的比较少,可以开辟10个空间来缓存对应图片。(消耗内存)
具体存储Size上设计需要考虑图片大小本身以及不同图片大小的具体使用频度高低,来分别考虑对待去设计存储容量的大小,通过队列(先进先出)的方式储存图片。
以队列先进先出的方式淘汰
LRU算法(最近最久未使用)如30分钟之内是否使用过?
定时检查(不推荐) —— 定时器每隔30秒进行我们图片存储数据遍历,查看哪个图片上次使用时间距离当下时间超过30分钟,如果超过就把它移除掉,但是此方案损耗性能,不划算的。
提高检查触发频率
每次进行读写时:比如在每次进行图片读写的时候,进行图片列表遍历的检查,如果发现某一张图片上次使用时间距离当下时间超过30分钟,那么我们从相应的数据结构中移除。
前后台切换:比如在前后台切换的时候,去检查哪个图片上次使用时间距离当下时间超过30分钟,那么我们从相应的数据结构中移除。
存储方式
大小限制(比如100MB)
淘汰策略(如某一张图片片存储时间距今已超过7天)
图片请求最大并发量 —— 在同一时间最大并发请求的图片数量要有限制
请求超时策略 —— 网络图片如果超时,可以通过重试的机制再次请求图片,如果两次都失败,那么就不去请求这张图片。
请求优先级 —— 下载的图片是否是当下用户最紧急使用的,如果是的话优先级就要高一些,其他的就要低一些。
应用策略模式对不同图片格式进行解码。
磁盘读取后 —— 从磁盘读取后直接进行图片解码放在内存当中,可以减少主线程压力。
网络请求返回后 —— 网络请求返回后进行图片解码在回传给内存模块,通过管理者在内存模块中进行缓存。
流程图:
记录器,由记录器负责对每一条时长统计的数据进行记录。
1:页面氏的记录器 —— 记录用户读取访问一个页面的时长,一般从页面push开始作为阅读时长的开始节点,pop之后代表这条记录的结束。
2: 流式的记录器 —— 新闻的阅读时长记录。
3:自定义式的记录器 —— 由业务方来控制具体的记录开始和结束的逻辑。
记录管理者,通过记录器通过记录的时长统计数据需交给记录管理者来进行管理。
1:记录缓存 —— 通过记录器锁记录的数据交给管理者进行缓存,缓存由记录管理者下的子模块记录缓存来维护。
2:磁盘存储 —— 如果程序杀死手机断电放在内存的时长记录就会丢失,为了解决这个问题,在记录管理者模块中就用到磁盘存储模块维护处理异常场景,解决可能导致内存缓存丢失的问题。
3:上传器 —— 记录管理者模块上传器模块,用于将本地记录下来的时长统计数据上传给Server。
基于不同分类场景提供的关于记录的封装,适配
定时写磁盘 —— 每隔15分钟或者每满多少条就做磁盘的一个写入,一定程度上降低我们记录的丢失率
限定内存缓存条数(如10条),超过该条数,既写磁盘
在前后台切换
从无网到有网的变化
通过轻量接口捎带
立刻上传
延时上传
定时上传
MVC 允许在不改变视图的情况下改变视图对用户输入的响应方式,用户对View的操作交给了Controller处理,在Controller中响应View的事件调用Model的接口对数据进行操作,一旦Model发生变化便通知相关视图进行更新。
MVVM与MVC最大的区别就是:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变。
MVVM
中,view
和 view controller
正式联系在一起,我们把它们视为一个组件view
和 view controller
都不能直接引用model
,而是引用视图模型(viewModel
)viewModel
是一个放置用户输入验证逻辑,视图显示逻辑,发起网络请求和其他代码的地方MVVM
会轻微的增加代码量,但总体上减少了代码的复杂性
优点:
View
可以独立于Model
变化和修改,一个 viewModel
可以绑定到不同的 View
上viewModel
里面,让很多 view
重用这段视图逻辑viewModel
,设计人员可以专注于页面设计MVVM
模式可以针对 viewModel
来进行测试缺点:
1.看起来代码会比MVC多点
2.需要对每个Controller实现绑定,类似于RAC
调用UIView的setNeedsDisplay,只是给对应视图打了一个脏标记,而他真正发生实际绘制是在当前RunLoop将要结束的时候才进行实际绘制动作。
反向更新机制通过View通过反向查找到viewModel变更对应业务数据打脏标记,在下次reload之前去反向更新。
预排版解决了性能方面的问题。
独立于App的通用层 —— 比如时长统计,崩溃统计,网络第三方库。
通用业务层 —— 基础组件,image的封装等
中间层 —— 协调和解耦
业务层ABCD
OpenURL
依赖注入