全方位剖析iOS高级技术问题(十)之架构&框架

3,759 阅读5分钟

本文主要内容

一.图片缓存
二.阅读时长统计
三.复杂页面架构
四.客户端整体架构

截屏2022-09-22 14.17.43.png

引入问题:架构和框架运用到日常开发过程,要解决的问题是什么?

  • 模块化
  • 分层
  • 解耦
  • 降低代码重合度

一.图片缓存

1.1、怎样设计一个图片缓存框架

  • 管理者Manager:图片缓存框架首先需要一个管理者用以协调和调度框架内部的各个模块;
    • 内存:负责内存管理的模块,关于图片的缓存;
    • 磁盘:图片磁盘缓存;
    • 网络:通过网络下载图片;
  • Code Manager
    • 图片解码
    • 图片压缩/解压缩

1.2、图片读写

问题一:图片通过什么方式进行读写,过程是怎样的?

  • 以图片URL的单向Hash值作为Key(多级缓存提高查找效率) 截屏2022-09-22 14.32.42.png

1.3、内存设计

问题二:内存的设计上需要考虑哪些问题?

  • 存储的Size

截屏2022-09-22 14.37.51.png

  • 淘汰策略
    • 以队列先进先出的方式淘汰 截屏2022-09-22 14.39.25.png

    • LRU算法,即最近最久未使用算法(如30分钟之内是否使用过) 截屏2022-09-22 14.42.22.png

1.4、磁盘设计

问题三:磁盘设计需要考虑哪些问题?

  • 存储方式
  • 大小限制(如100MB)
  • 淘汰策略(如某一图片存储时间距今已超过7天)

1.5、网络设计

问题四:网络设计需要考虑哪些问题?

  • 图片请求最大并发量
  • 请求超时策略
  • 请求优先级

1.6、图片解码

问题五:对于不同格式的图片,解码采用什么方式来做?

  • 应用策略模式对不同图片格式进行解码。

问题六:在哪个阶段做图片解码处理?

  • 磁盘读取后
  • 网络请求返回后

1.7、线程处理

外界通过图片URL对应的Key对图片进行获取时,首先经由Manager到内存中查找。

  • 如果在内存缓存中命中,直接把内存结果返回给调用方;
  • 如果在内存缓存中没有对应图片的数据存在,需要通过Manager读取磁盘缓存数据,如果在磁盘缓存中找到图片数据,就把数据返回给调用方,同时将磁盘中读取的图片数据对应的放到内存缓存当中,方便下次更快使用;
  • 如果在磁盘缓存中没有读取到对应图片数据,需要发起网络请求,将网络结果返回给调用方,同时放到内存缓存中!

截屏2022-09-22 14.52.37.png

二.阅读时长统计

2.1、怎样设计一个时长统计框架?

截屏2022-09-22 15.04.21.png

2.2、为何要有不同类型的记录器,考虑是什么?

  • 基于不同分类场景提供的关于记录的封装、适配;

2.3、记录的缓存和存储

问题一:记录的数据会由于某种原因丢失,怎样处理?
降低丢失率

  • 定时写磁盘
  • 限定内存缓存条数(如10条),超过该条数,即写磁盘

2.4、上传记录器

问题二:关于延时上传的具体场景有哪些?
对应立即上传,如果每一条记录都立即上传会消耗客户端的性能和流量。

  • 前后台切换
  • 从无网络到有网络的变化
  • 通用轻量接口捎带(少见)

问题三:长传时机是怎样把控的?

  • 立即上传
  • 延时上传
  • 定时上传

三.复杂页面架构

  • 微博APP的正文页
  • 去哪儿旅行APP的航班列表
  • 今日头条、腾讯新闻等资讯类APP的多签首页
  • 脉脉APP的多签首页

3.1、总体架构

截屏2022-09-23 09.37.15.png

  • 视图层:View & ViewController

截屏2022-09-23 09.38.51.png

  • 业务逻辑层:ViewModel

截屏2022-09-23 09.40.35.png

  • 数据层:Engine & Model

截屏2022-09-23 09.41.18.png

3.2、数据流

3.2.1 数据流流向

截屏2022-09-23 09.44.02.png

3.2.2 数据及数据关系

  • 网络数据:包括【一级评论】、【二级评论】、【转评赞】、【广告、推荐等其他数据】等;
  • 业务数据:包括【id data】、【int type】等;
  • UI数据:【imageObj】、【labelObj】(frame/value);

截屏2022-09-23 09.49.32.png

3.2.3 反向更新

截屏2022-09-23 09.50.40.png

3.3 复杂页面架构总结

  • MVVM框架思想
  • ReactNative的数据流思想
  • 系统UIView更新机制的思想
  • FaceBook的开源框架AsyncDisplayKit关于预排版的设计思想

3.3.1 MVVM

即Model + View + ViewModel

  • Model:数据层
  • View:视图层和ViewController
  • ViewModel:业务逻辑层

1、UIViewController对ViewModel进行强引用或ViewModel作为其成员变量,ViewModel通过Block的方式将输出结果回传给使用方,或者通过RAC函数响应式编程把对应的输出回传给视图;(View层<==>业务员逻辑层)

2、ViewModel对数据层Model有强引用或Model作为其成员变量,数据层Model通过Block方式或代理方式回传数据给业务逻辑层;(数据层<==>业务员逻辑层)

3、View层包含View视图层和ViewController层。

3.4、RN数据流思想

总结:任何一个子节点或子孙节点没有权利做自己的变化更新,必须要把自己的变化更新消息反向传递给根节点,由根节点自顶向下询问哪些需要更新

截屏2022-09-23 10.15.17.png

四.客户端整体架构

  • 独立于APP的通用层(可以放在任何APP作为底层框架):比如包含时长统计框架、崩溃的统计、网络的第三方库等;
  • 通用业务层:通用基础组件,比如包含自定义步进控件、特殊UIImageView的封装等;
  • 中间层:协调解耦作用;
  • 业务层

截屏2022-09-23 10.22.37.png

问题一:业务之间的解耦通信方式

  • OpenURL

  • 依赖注入

    1.把业务C注入到中间层,业务A去中间层获取;
    2.业务C实现中间层的代理/协议方法并返回一个具体对象给中间层,在业务A使用的时候,通过对应协议从中间层中根据某一方法获取遵从某一协议的一个实例。在业务A中可以把这个实例当做遵从某一协议的透明对象,这样就达到解耦目的。
    

截屏2022-09-23 10.31.04.png

本文总结

图片缓存

阅读时长统计

复杂页面架构

客户端整体架构

有任何问题,欢迎👏各位评论指出!觉得博主写的还不错的麻烦点个赞喽👍