iOS存储与网络、多媒体技术和设计模式| 青训营笔记

47 阅读6分钟

这是我参与「第四届青训营 -iOS场」笔记创作活动的的第6篇笔记

存储

沙盒

  • iOS文件系统,沙盒
  1. MyApp.app,该目录包含了应用程序本身的数据
  2. Documents,使用这个目录保存用户数据
  3. Libaray,保存配置文件和数据库文件,使用NSUserDefaults写的数据都会保存在Libaray/Preferences目录下的一个plist文件
  4. tmp,保存临时文件
// doucments
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
// libaray
NSString *libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
// cache
NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// tmp
NSString *tmpDir = NSTemporaryDirectory();
NSLog(@"%@\n%@\n%@\n%@", docDir, libDir, cacheDir, tmpDir);

Bundle

  • 本质上是App安装包,包括App资源
  1. Info.plist,版本信息、权限信息
  2. Executable,可执行文件
  3. Resource files,资源文件
  4. Other support files,动态库
  • 生成,编译时会生成目标文件,链接静态文件,形成可执行文件;在运行时,链接动态库,进行运行时解析 image.png
NSString *path = [[NSBundle mainBundle] pathForResource:@"XXX" ofType:""];

序列化

  • 字符串写入文件
[name writeToFile:path atomically:YES encoding:NSUnicodeStringEncoding error:nil];
  • NSData读出
// NSDataReadingUncached:指示文件不应存储在文件系统缓存中的提示,只读取一次数据. (对于一次读取和丢弃的数据,此选项可以提高性能.)
// NSDataReadingMappedIfSafe:在不丢失的数据的情况下,文件应该映射到虚拟内存的,
// NSDataReadingMappedAlways:尽可能将文件映射到虚拟内存
[NSData dataWithContentsOfFile:path options:<#(NSDataReadingOptions)#> error:nil];
  • 序列化与反序列化
  1. 序列化,将对象转换为字节序列
  2. 反序列化,将字节序列恢复为对象
  3. 为什么需要序列化,只能传输二进制的数据,把kv概念,转换成二进制
  • 序列化协议,xml/json/protobuf image.png
  • NSJSONSerialization
// 序列化
[NSJSONSerialization dataWithJSONObject:<#(nonnull id)#> options:<#(NSJSONWritingOptions)#> error:<#(NSError *__autoreleasing  _Nullable * _Nullable)#>]
// 反序列化
[NSJSONSerialization JSONObjectWithData:<#(nonnull NSData *)#> options:<#(NSJSONReadingOptions)#> error:<#(NSError *__autoreleasing  _Nullable * _Nullable)#>]

其他存储

网络

  1. NSURLSession原生
  2. NetWork.framework
  3. TTNewworkManager 字节跳动开源
  • NSURL
  1. 统一资源定位符,解析URL字符串的各个部分的对象
  2. 文本路径也可以作为URL,有相应的初始化方法
  • NSURLRequest
  1. 请求
  • NSURLSession,整个请求的流程
  1. NSURLSessionConfiguration,对NSURLSession初始化进行配置,设置请求的cookie、密钥、缓存、请求头等参数
  2. NSURLSessionTask,负责执行具体请求的task,由session创建
  3. NSURLSessionTaskDelegate,不同任务的关键阶段定义的代理方法

多媒体技术

相册权限

  • 通过Info.plist设置资源权限申请 image.png
  • 需要导入Phohos.framework/PhotosUI.framework
PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
// 选择限制
config.selectionLimit = 3;
// 过滤器,过滤出图片
config.filter = [PHPickerFilter imagesFilter];

PHPickerViewController *pickerViewController = [[PHPickerViewController alloc] initWithConfiguration:config];
pickerViewController.delegate = self;
[self presentViewController:pickerViewController animated:YES completion:nil];
  • 权限区别 image.png

视频播放

  • AVPlay视频播放
NSURL *url = [NSURL fileURLWithPath:path];
AVPlayer *play = [AVPlayer playerWithURL:url];
[play play];
  • 音效配置

是否引起不支持的混音的App中断,两个App的声音冲突时,另一个App是否会被中断 image.png

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
  • 画中画,需要导入AVKit.framework
AVPictureInPictureController *pc = [[AVPictureInPictureController alloc] initWithPlayerLayer:player];

滤镜

  • 框架 image.png
  • OpenGL状态机,一台保存状态,并根据当前状态进行相应输出的机器;进行特殊状态时,不再接收输入,ring值工作
  1. 非常庞大,首先要创建一个OpenGL的上下文
  2. 面向过程,可以封装为面向对象
  3. 切换上文开销大,可创建多个上下文独立使用,不同线程使用不同的上下文,可共享纹理、缓冲区
  • 渲染管线,流水线渲染,其中顶点着色器和片元着色器可编程
  1. 顶点着色器,顶点元素由CPU传个GPU
  2. 图元装配,组装成形状
  3. 栅格化,将图元转换为像素
  4. 片元着色器,给像素赋予真正的颜色
  5. 测试与混合,判断这个像素在前还是在后,调整透明度和深浅 image.png

设计模式

类蔟

  • NSNumber是抽象工厂模式的实践,管理隐藏在公共抽象父类下的具体私有子类,Number作为抽象工厂类,数据类型作为具体的实现
  1. 优点,隐藏实现细节;简化开发成本;便于增加实际类型;减少if-else
  2. 缺点,抽象工厂增加方法,所有子类都需要进行必要的实现,已有的类蔟不好扩展 image.png

观察者模式的应用

  • NSNotificationCenter,内部维护三个数据结构,有主题和Object的Map/没主题有Object的Map/没主题没Object的链表,收到对应的通知后,在对应的数据结构中进行匹配调用观察者的方法
  • KVO,当进行KVO时,创建了新的子类(继承原先的子类),原先实例对象的isa指针指向新的子类;新子类的内部setter方法被重写,调用KVO对应的方法 image.png
  • 优点
  1. 表示层和数据层逻辑分离
  2. 广播通信,简化一对多系统设计
  3. 满足开闭原则
  • 缺点
  1. 容易产生循环依赖,互相监听
  2. 广播作用域没有权限限制

开发范式

  • 本质
  1. 数据管理
  2. 数据加工
  3. 数据展示
  • 解决的核心问题
  1. 支撑业务
  2. 控制复杂度,便于阅读代码,理解业务
  3. 提升研发效率
  • 胖瘦Model
  1. 瘦,追求细粒度的Model,只提供基本属性
  2. 胖,根据业务要求,返回适合的属性格式,包含弱业务逻辑,复用性不强
  • 发展 image.png

MVC

  • 结构
  1. Model,数据
  2. Controller,监听View的交互事件
  3. View,界面
  4. model和view不应该感知对方的存在,便于复用
  5. controller可以对model和view进行调用和处理
  6. view和controller之间的通信方式,addTarget、代理、数据源 image.png
  • 设计模式
  1. 组合模式,model和view组合在controller中
  2. 命令者模式,controller通过target决定如何响应view的行为
  3. 观察者模式,kvo
  4. 策略模式,不同响应方式
  5. 中介者模式,controller作为媒介
  • 问题
  1. Controller臃肿,包括很多实际的View和事件处理
  2. Model太过于轻量级,大多数只是属性的映射
  3. 遗失的网络请求,与API通信的代码,没有专属的层次
  4. 较差的可测试性,Controller耦合Model和View

MVCS

  • 瘦Model只用于表达数据
  • 存储/处理交给Store层
  • 拆分Controller关于数据处理的部分 image.png

MVVM

  • 其中的View实际上是Controller+View
  • ViewModel
  1. 视图层数据的提供者,对Model层的数据进行包装
  2. 视图层交互的响应者,进行view的业务逻辑的处理
  3. 在MVC基础上把Controller拆分出一部分,专门处理view和数据的业务逻辑
  • Rx提供了很好的数据绑定方法,利于实现MVVM

VIPER

  • View 视图显示
  • Interactor 业务逻辑
  • Presenter 交互
  • Entity 实例数据
  • Router 路由 image.png

MVX

  • 理想架构
  1. 单向数据流
  2. 层与层界限清晰
  • 特点
  1. 拆分细粒度高
  2. 层级解耦
  3. 各部分复用性高
  4. 易用性、可观测性 image.png