文章目录
- 一、设计模式的六大原则
- 二、 设计模式有哪些,简要叙述?
- 三、MVC的理解
- 四、代理委托模式
- 五、观察者模式
- 1. KVO原理:
- 2. KVO的详细流程
- 3. 如何手动触发KVO:
- 4. swift的kvo:
- 六、工厂模式
- 七、单例模式
- 八. KVC实现原理
- 1. 赋值实现原理
- 2. 取值实现原理
- 九、RAC副作用
一、设计模式的六大原则
- 单一原则:
一个类只负责一件事:UIView、CALayer - 开闭原则
对修改关闭、对拓展开放 - 接口隔离原则
使用多个专门的协议、而不是一个庞大臃肿的协议
协议中的方法尽量少
UITableView - 依赖倒置原则
抽象不应该依赖于具体实现,具体实现可以依赖于抽象 - 里氏替换原则
KVO
父类可以被子类无缝替换,且原有功能不受任何影响 - 迪米特法则
一个对象应当对其他对象有尽可能少的了解
高内聚、低耦合
二、 设计模式有哪些,简要叙述?
- MVC模式:Model View Control,把模型 视图 控制器 层进行解耦合编写。
- MVVM模式:Model View ViewModel 把模型 视图 业务逻辑 层进行解耦和编写。
- 单例模式:通过static关键词,声明全局变量。在整个进程运行期间只会被赋值一次。
- 观察者模式:KVO是典型的通知模式,观察某个属性的状态,状态发生变化时通知观察者。
- 代理模式:代理+协议的组合。实现1对1的反向传值操作。
- 工厂模式:通过一个类方法,批量的根据已有模板生产对象。
- 策略模式:把一些独立的算法单独封装起来
- 适配器模式:根据不同的场景选择不同的对象
- 模板模式:例如项目基类BaseViewController
三、MVC的理解
数据管理者(M)、数据展示者(V)、数据加工者(C)
M应该做的事:
- 给ViewController提供数据
- 给ViewController存储数据提供接口
- 提供经过抽象的业务基本组件,供Controller调度
C应该做的事:
- 管理View Container的生命周期
- 负责生成所有的View实例,并放入View Container
- 监听来自View与业务有关的事件,通过与Model的合作,来完成对应事件的业务
V应该做的事
- 响应与业务无关的事件,并因此引发动画效果,点击反馈
- 界面元素表达
四、代理委托模式
A类想要做某事,但是A类并不具备做某事的方法
B类能够做某事,但是B类并没有做某事的意愿
A类拜托B类帮助自己做某事的过程,就被叫做代理委托模式
步骤:
- 制定协议,委托人想要做的事
- 设置代理属性,执行人是谁
- 指定代理对象
- 代理对象 服从 委托协议
- 代理对象 实现 委托协议中的必须实现的方法
- 委托对象在合适的时机让代理对象执行协议中的方法。
// 判断委托人能够做某事
if ([self.delegate respondsToSelector:@selector(方法名)]) {//如果代理方实现了协议中得方法,就让代理去执行该方法[self.delegate 方法];}
五、观察者模式
当某处发生某事,观察者会相应做出处理。
1. KVO原理:
当观察一个对象时,runtime会动态创建继承自该对象的类,并重写被观察对象的setter方法,重写的setter方法会负责在调用原setter方法前后通知所有观察对象值得更改,最后会把该对象的isa指针指向这个创建的子类,对象就变成子类的实例。
KVO就是通过一种叫isa-swizzling
的技术实现的
2. KVO的详细流程
- 监听者调用监听的方法
- 被监听者派生一个中间类。被监听对象的
isa
指针指向派生类。 - 被监听的属性发生变化,由中间类触发监听通知
- 监听者收到通知。触发
observeValueForKey:ofObject:change:context:
3. 如何手动触发KVO:
在setter方法里,手动实现NSObject两个方法:willChangeValueForKey、didChangeValueForKey
4. swift的kvo:
继承自NSObject的类,或者直接willset/didset实现。
六、工厂模式
工厂模式,也被称为需构造器(Virtual Constructor)。
就是将类的实例化延迟到子类当中进行。
工厂模式主要解决的问题是对象创建的时机,它提供了一种扩展的策略,很好的符合了开放封闭原则。
工厂模式的使用时机:当一个类不知道它所必须创建的对象是什么类,或者一个类希望它的子类自己决定创建何种对象
七、单例模式
就是一个类在全局仅能够持有一个对象,并且对象不被释放。这种机制就叫单例模式
在使用单例的时候,创建对象一定要使用单例方法来创建,
切不可通过alloc copy 等方式随意创建单例对象,这样会对内存造成很大的负担。
八. KVC实现原理
KVC是一种间接访问对象属性的机制。
1. 赋值实现原理
- 查找是否实现setter方法,如果有,优先调用setter方法完成赋值(注意:set后面的键的第一字字母必须是大写!!)
- 当没找到setter方法,调用accessInstanceVariablesDirectly询问。
如果返回YES,顺序匹配变量名与 _,_is,,is,匹配到则设定其值
如果返回NO,结束查找。并调用 setValue:forUndefinedKey:报异常 - 如果既没有setter也没有实例变量时,调用 setValue:forUndefinedKey:
2. 取值实现原理
- 查找是否实现getter方法,依次匹配
-get<Key>
和-<key>
和is<Key>
,如果找到,直接返回。
需要注意的是 :
如果返回的是对象指针类型,则返回结果。
如果返回的是NSNumber转换所支持的标量类型之一,则返回一个NSNumber
否则,将返回一个NSValue - 当没有找到getter方法,调用accessInstanceVariablesDirectly询问
如果返回YES, _,_is,,is,找到了返回对应的值
如果返回NO,结束查找。并调用 valueForUndefinedKey: 报异常 - 如果没找到getter方法和属性值,调用 valueForUndefinedKey: 报异常
九、RAC副作用
副作用指的就是RAC改变了外界的状态(例如全局属性的赋值,多次网络请求,线程锁等),这些可能会导致一个问题,那就是同样的输入可能会导致不同的输出,同时也增加了我们排查代码错误的难度。
以网络请求为例,现实中一般是不会这么用的,这里只是举个例子.请求若使用冷信号,我们对这个冷信号在进行一些操作的时候,臧成威前辈讲其实内部对一些信号的操作是再次订阅的过程,那么最后你可能会导致多次请求的问题出现,这便可以理解为副作用.严格地讲iOS开发其实就是一个在创造副作用的过程.现实中我们一般会把请求放到viewmodel中,只请求一个数据,然后将数据转成相应的属性暴露在.h文件,然后控制器在和数据进行绑定,这样做非常的优雅.