iOS面试题收纳-设计模式

273 阅读6分钟

什么是设计模式

简述

  • 一套被反复使用的代码设计经验的总结
  • 好处是:可重用代码、让代码更容易被他人理解、保证代码可靠性
  • 一般与编程语言无关,是一套比较成熟的编程思想

分类

创建型模式

对象实例化的模式,用于解耦对象的实例化过程

  • 单例模式、工厂方法模式等等
结构型模式

把类或对象结合在一起形成一个更大的结构

  • 代理模式、适配器模式、组合模式、装饰模式,等等
行为型模式

类或对象之间如何交互,及划分责任和算法

  • 观察者模式、命令模式、责任链模式等等

iOS有哪些常见的设计模式

  • 单例模式
    1. 单例保证了应用程序的生命周期内仅有一个该类的实例对象,而且易于外界访问。
    2. 在iOS SDK中UIApplication、NSBundle、NSNotificationCenter、NSFileManager、NSUserDefault、NSURLCache等都是单例
  • 委托模式
    1. 委托Delegate是协议的一种,通过@protocol方式实现,常见的有tableView、textField等
  • 观察者模式
    1. 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。
    2. 在iOS中,观察者模式的具体实现有两种:通知机制(notification)和KVO机制(Key-value Observing)

单例会有什么优缺点

主要优点:

  • 提供了对唯一实例的受控访问
  • 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象。单例模式无疑可以提高系统的性能
  • 允许可变数目的实例

主要缺点:

  • 由于单利模式中没有抽象层,因此单例类的扩展有很大的困难
  • 单例类的职责过重,在一定程度上违背了“单一职责原则”
  • 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失

面向对象的几个设计原则

开闭原则(Open Closed Principle,OCP)

  • 开闭原则是总纲,它指导我们要对扩展开放,对修改关闭
  • 对于一个类,最好不让外部修改它内部的实现,而是通过组合、继承等手段来扩展类的功能

单一职责原则(Single Responsibility Principle, SRP)

  • 单一职责原则指导我们实现类要职责单一。
  • 一个类实现的职责要单一,不要弄成大杂烩,可以通过拆分类的方式来精简类。

接口隔离原则(Interface Segregation Principle,ISP)

  • 接口隔离原则指导我们在设计接口的时候要精简单一。
  • 一个类暴露的接口要尽量少。
  • 每个接口实现的功能要单一,一个接口不能做好几件事,通过拆分接口来让接口功能更加单一。

依赖倒置原则(Dependency Inversion Principle,DIP)

  • 依赖倒置原则指导我们要面向接口编程而不是实现编程。
  • 面向接口编程的优势有: 1、通过暴露接口给外部使用,向外部隐藏实现细节;即使实现发生变化,外部也不需要改变调用接口。 2、通过实现多个接口,来避免多继承带来的类型爆炸问题。 3、通过接口来实现多态。 框架实现中一般会大量用面向接口编程。比如iOS框架中大量用协议来实现多继承。

里氏替换原则(Liskov Substitution Principle,LSP)

  • 里氏替换原则指导我们不要破坏继承体系。
  • 任何使用父类的地方都能使用子类。

最少知识原则(Least Knowledge Principle,LKP)或者迪米特法则(Law of Demeter,LOD)

  • 迪米特法则指导我们要降低耦合。
  • 类的实现要高内聚、低耦合。

组合/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)

  • 组合/聚合复用原则指导我们优先使用组合而不是继承。
  • 使用组合而不是继承,不需要了解原类的实现,即时原类发生了变化,影响也也可以降至最低。
  • 在UI编程上,大量的使用组合模式,通过组合控件来实现复杂界面。

讲一下MV(X);V视图(包括vc),M业务数据,X(C,VM,P)业务逻辑的处理者,作为M、V的桥梁

  • MVC

objc_mvx_mvc.png

  • iOS开发实际应用时的MVC

objc_mvx_mvc_oc1.png

objc_mvx_mvc_oc0.png

  • MVP

objc_mvx_mvc.png

跟MVC相比,我们把所有view相关的东西都化作view模块,其余的逻辑放到一个模块,于是就有了MVP

  • MVVM

objc_mvx_mvvm.png

  • VIPER

objc_mvx_viper.png VIPER对职责划分了5个模块。

  • View(页面) - 展示给用户的界面
  • Interactor(交互器) - 包括数据(Entities)或者网络相关的业务逻辑。
  • Presenter(展示器) - 包括 UI(but UIKit independent)相关的业务逻辑,可以调用 Interactor 中的方法。
  • Entities(实体) - 纯粹的数据对象。不包括数据访问层,因为这是 Interactor 的职责。
  • Router(路由) - 负责 VIPER 模块之间的转场

详情请看这篇文章

如何设计一个时长统计框架

记录器

  • 页面式记录器
  • 流式记录器
  • 自定义式

记录管理者

  • 内存记录缓存
  • 磁盘存储
  • 上传器

如何降低数据的丢失率?

  • 定期写入磁盘
  • 每当达到某个值的时候,就写入磁盘

记录上传的时机

  • 前后台切换的时候可以上传
  • 从无网到有网切换的时候可以上传

上传时机的选择

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

如何设计一个图片缓存框架

可以模仿 SDWebImage 来实现

  • Manager
  • 内存缓存
  • 磁盘缓存
  • 网络下载
  • Code Manager
    • 图片解码
    • 图片解压缩

图片的存储是以图片的单向 hash 值为 Key

内存设计需要考虑的问题

存储的 Size

因为内存的空间有限,我们针对不同尺寸的图片,给出不同的方案

  • 10K 以下的50个
  • 100Kb 以下的20个
  • 100kb 以上的10个

淘汰的策略

内存的淘汰策略 采取 LRU(最近最少使用算法)

触发淘汰策略的时机有三种

  • 1.定期检查(不建议,耗性能)
  • 2.提高检查触发频率(一定要注意开销)
    • 1.前后台切换的时候
    • 2.每次读写的时候

磁盘设计需要考虑的问题

  • 存储方式
  • 大小限制(有固定的大小)
  • 移除策略(可以设置为7天或者15天)

网络设计需要考虑的问题

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

图片解码

应用 策略模式,针对 jpgpnggif 等不同的图片格式进行解码

图片解码的时机

  • 在 子线程 图片刚下载完时
  • 在 子线程 刚从磁盘读取完时

避免在主线程解压缩、解码,避免卡顿

一个换肤方案,怎么设计,有哪些类

参考框架SwiftTheme,DKNightVersion

如何设计一个缓存框架

www.dazhuanlan.com/seatalker/t…

怎么检测OOM

www.jianshu.com/p/c2e2e53ff…

www.infoq.cn/article/ox7…

blog.csdn.net/TuGeLe/arti…

怎么进行死锁检测

juejin.cn/post/703745…