# 框架设计 ## 图片框架 ### 角色 - Manager - 内存 - 磁盘 - 网络 - Code Manager - 图片解码 - 图片压缩/解压缩 ### 图片读写过程 - 以图片 url 的 hash 值为 key,存储 ### 读取过程 ### 内存设计 - 内存存储的空间 - 10kb 以下,使用场景多,设计50张容量 - 100kb 以下,使用场景次之,设计20张容量 - 100kb 以上,使用场景最小,设计10张容量 - 淘汰策略 队列实现,先进先出。 ### 淘汰策略 LRU,最近最久未使用算法。比如3天内没有使用过的,则认为需要被淘汰。 ### 淘汰时机 - 定时检查,比如 30分钟检查一次 - 提高检查频率: - 每次进行图片读写时 - 前后台切换时 ### 磁盘设计 - 存储方式 - 大小限制(如200MB) - 淘汰策略:如果某一张图片存储时间距今已经超过7天 ### 网络设计 - 图片请求的最大并发量 - 请求超时策略。超时重试1次,再次超时则取消 - 请求优先级 ### 图片解码 对于不同格式的图片,图片解码怎么处理? 应用**策略模式**,对不同图片格式进行解码。一方面可以解码不同格式、另一个方面替换解码算法,对于稳定性有帮助 在哪个阶段进行解码? 磁盘读取后、网络请求返回后 ### 线程处理 ## 阅读时长记录器 ### 记录器种类 - 页面式:普通的 push、pop 页面 - feed 流式:类似 weibo 这种 feed 流式的记录 - 自定义式:可拓展性的体现,面向未来 QA:为什么要有不同类型的记录器? - 基于不同分类场景提供的关于记录的封装、适配 - ### 记录数据存储 - 内存缓存 - 磁盘存储 ### 准确性 数据收集(存储)、上报(移除)2个核心流程。准确性也和这2个方面息息相关。 - 定时写磁盘 从内存中 flush 到本地磁盘。定时器1分钟 flush 一次 - 限定内存缓存条数。超过该条数,即写磁盘。内存记录每满10条 flush 一次 ### 上传策略 思考: - 需要立马上传吗?每收集到1次页面阅读时长就需要立马上传1次吗?ROI 衡量。性能、线程数 - 关于延时上传的场景有哪些? 上传时机: - 定时器,比如每5分钟上传1次。 - 前后台切换,比如从后台切换到前台触发1次上传逻辑 - 无网切换到有网 ### 网络上传效率 自定义报文,高效传输。 iOS 小端序,网络大端序。 ## 复杂页面架构设计 - MVVM - Redux 数据流 ## 客户端架构 ## 业务之间解耦后的通信方式 - openURL - 依赖注入:中间层 ## AFNetworking ### 主要类关系图 ### AFURLSessionManager - 创建和管理 NSURLSession、NSURLSessionTask - 实现 NSURLSessionDelegate 协议代理方法,处理网络请求的重定向、认证、网络数据的处理 - 引入 AFSecurityPolicy,用来保证请求安全 - 引入 AFNetworkReachabilityManager 监控网络状态 ## SDWebImage ### 架构图 ## 图片加载流程 - 查找内存缓存 - 查找磁盘缓存 - 网络下载图片并磁盘缓存 ## AsyncDisplayKit ### 主要处理问题 主要通过减轻主线程压力,尽量将一些可以放到子线程的任务都放到子线程处理,减轻主线程压力 主要分3方面: - UI 布局 layout:文本宽高计算、视图布局计算 - 渲染 Rendering:文本渲染、图片解码、图形绘制 - UIKit Objects:对象创建、调整、销毁 ### 基本原理 - UIView 作为 CALayer 的代理实现。CALayer 作为 UIView 的实例变量,负责展示规工作。 - 针对 UIView 的修改,都抽象为针对 ASNode 的修改,这些修改可以在子线程进行。针对 ASNode 的修改和提交,会对其进行封装,提交到一个全局容器中。 - 对 Runloop 状态进行监听,进入休眠前,ASDK 执行该 loop 内提交的所有任务。