delegate
优点:
- 语法严格, 所有监听的事件必须是在 delegate 协议中有清晰的定义
- 如果 delegate 中的一个方法没有实现那么就会出现编译警告/错误
- 协议必须在 controller 的作用域范围内定义
- 在一个应用中的控制流程是可跟踪的并且可识别的
- 在一个控制器中可以定义多个不同的协议, 每个协议有不同的 delegates
- 没有第三方对象要求保持/监视通讯过程
- 能够接收调用的协议方法的返回值. 这意味着 delegate 能够提供反馈信息给controller
- 经常被用在存在父子关系的对象之间的通信, 例如控制器和控制器的 View
缺点
- 需要定义很多代码: 1.协议定义:2.Controller的delegate属性:3.在delegate本身中实现delegate方法定义
- 在释放代理对象时, 需要小心的将delegate改为nil. 一旦设定失败,那么调用释放对象的方法将会出现内存 crash
- 在一个 Controller 中有多个 delegate 对象, 并且 delegate hi是遵守同一个协议, 但还是很难告诉多个对象同一件事件.
- 经常用在一对一的通信.
Notification
优点
- 代码量小, 实现简单
- 对于一个发出的通知, 多个对象能做出反应, 即一对多的实现方式.
- Controller 能传递 Context 对象, Context 对象存储关于发送通知的信息.
缺点
- 编译器不会检查通知是否能够被观察证正确的处理
- 在释放注册的对象时, 需要在通知中心取消注册
- 在调试的时候应用的工作以及控制过程很难跟踪
- 需要第三方对象来管理Controller与观察者对象之间的联系
- controller 和观察者需要提前知道通知名称, UserInfo dictionary key. 如果这些没有工作区间定义, 那么会出现不同步的情况:
- 通知发出后, Controller 不能从观察者活得任何的反馈信息
KVO
优点
- 能够提供一种简单的方法实现两个对象间的同步.
- 能够对非我们创建的对象, 即内部对象的状态改变做出响应, 而且不需要改变内部对象(SDK对象)的实现
- 能够提供观察的属性的最新值以及先前值
- 用 key path 来观察属性, 因此也可以观察嵌套对象
- 完成了对观察对象的抽象, 因为不需要额外的代码来允许观察值能够被观察
- 可以一对多
缺点
- 我们观察的属性必须使用 string 来定义, 因此在编译的时候不会出现警告和检查
- 对属性重构会导致我们的观察代码不可用
- 复杂的"IF"语句要求对象正在观察多个值. 这是因为所有的代码通过一个方法来指向.
- 当释放观察者时不需要移除观察者
从设计模式的角度去分析 Delegate, Notification, KVO 的区别
- 效率方面 delegate 比 NSNotification高. delegate 方法比 notification 更加直接, 最典型的特征是, delegate 方法往往需要关注返回值, 也就是 delegate方法的结果.比如 windowShouldClose, 需要关系返回的是 YES 还是 NO. 所以deleagete方法往往包含 should 这个很传神的词. 也就是好比你做我的delegate, 我会问你我想关闭窗口你还愿意吗? 你需要给我一个答案, 我根据你的答案来决定如何做下一步.相反的, notification 最大的特色就是不关心接受者的态度. 我直管把通告放出来, 你接受不接受就是你的事情, 同时我也不关心结果. 所以 notification 玩玩用 did 这个词汇, 比如 NSWindowDidResizeNotification, 那么 NSWindow 对象放出这个 Notification 后就什么都不管了, 也不会等待接受者的反应.
- KVO 和 NSNotification 和 delegate 一样, KVO 和 NSNotification 的作用也是类和类之间的通信, 和 delegate 不同的是
- KVO 和 NSNotification 都是负责发出通知, 剩下的事情就不管了, 所以没有返回值
- delegate 只是一对一, 而这俩个可以一对多.
总结
什么是设计模式
- 设计模式是为特定场景下的问题而制定的解决方案. 特定场景指问题所在的重复出现的场景, 问题指特定环境下你先达成的目标. 同样的问题在不同的环境下会有不同的限制和挑战. 定制的解决方案是指在特定环境下克服问题的限制条件而达成目标的一种设计
设计模式的分类
- 设计模式分为三种类型, 共 23 种
- 创建型模式: 单利模式, 抽象工厂模式, 建造者模式, 工厂模式, 原型模式.
- 结构型模式: 适配器模式, 桥接模式, 装饰模式, 组合模式, 外观模式, 享元模式, 代理模式.
- 行为型模式: 模板方法模式, 命令模式, 迭代器模式, 观察着模式, 中介者模式, 备忘录模式, 解释器模式(interpreter模式), 状态模式, 策略模式, 职责联模式(责任链模式), 访问者模式.
类工厂方法
- 类工厂方法的实现是为了向客户提供方便, 他们将分配和初始化合在一个步骤中, 返回被创建的对象, 并进行自动释放处理.
- 这些方法的形式是 + (type)className... (其中 className 不包括任何前缀)
- 工厂方法可能不仅仅为了方便使用. 他们不但可以将分配和初始化合在一起, 还可以为初始化过程提供对象的分配信息.
- 类工厂方法的另一个目的是使类(比如 NSWorkspace) 提供单利. 虽然 init... 方法可以确认一个类在每次程序运行过程中只存在一个实例, 但它需要首先分配一个"生的"实例, 然后还必须释放该实例. 工厂方法可以避免为可能没有用的对象盲目分配内存.
单例
单例模式的意思就是只有一个实例. 单例模式确保摸一个类只有一个实例, 而却自行实例化并像整个系统提供这个实例.
要点
- 一个类只能有一个实例
- 必须是自行创建的实例
- 必须自行向整个系统提供这个实例
优点
-实例控制: singleton 会组阻止其他对象是实例化自己的 singleton 对象的副本, 从而确保所有对象都访问唯一实例. - 灵活性: 因为类控制了实例化过程, 所以类可以更加灵活修改实例化过程.
手写单例
static Class *class;
+ (Class *)shareInstance {
if(!class) {
static dispatch once_t Token;
dispatch_once (&token, ^ {
class = [[class alloc] init];
};
}
return class;
}
简述观察者模式,
- 观察者模式 (Observer) 是一个或多个对象对另一个对象进行观察, 当被观察对象发生变化时, 观察者可以直接或间接的得到通知, 从而能自动的更新观察者的数据, 或者进行一些操作.
- 具体到 iOS 的开发中, 实现观察者模式常用的方式有 KVO 和 Notification 俩种.
- 俩者的不同在于, KVO是被观察者主动向观察者发送消息: Notification 是被观察者向 NotificationCenter 发送消息, 再由 NotificationCenter post 通知到每个注册的观察者.
MVC,单例, 代理
- MVC: 就是 Model-View-Controller 的缩写, M 指的是业务逻辑, V 指的是用户界面, C 指的是控制器. MVC是架构模式, 是讲 M 和 V 的代码分离, 从而使同一个程序有不同的表现形式.
- 单例模式: 一个类只有一个实例
- 代理模式: 代理模式给某一个对象提供一个代理对象, 并由代理对象控制对源对象的引用, 比如一个工厂生产了产品, 并不想直接卖给用户, 二十高了很多代理商, 用户可以直接找代理商买东西, 代理商从工厂进货, 常见的如QQ的自动回复就属于代理拦截, 代理模式在 iphone 中得到广泛应用.
测试, MVC 优点不正确的是
A. 低耦合性
B. 高重用性和可适用性
C. 较低的声明周期成本
D. 代码高效率
- 参考答案: D
- 理由: MVC 只是一个钟设计模式, 他的出现有比较久的历史了. Model-Controller-View 是在开发中最常见到的设计模式, 通过将 Model, View, Controller 三者相互联系, 以 Model 作为数据加工厂, 以 Controller 作为桥梁, 处理业务, 而 View 只是数据展示层, 理应与业务无关. MVC 设计模式降低了耦合性, 提供了重用性和适用性, 可以有效的提高开发效率.
MVVM
- MVVM 框架相对于传统的 MVC 来说, 主要区别在于把原本在 C 中 (ViewController) 的业务逻辑, 网络请求, 数据储存等操作和表现逻辑, 分离到 ViewModel 中, 从而是 ViewController 得到精简
- MVC 中, Controller 同时操作 Model 和 View; MVVM 中, ViewModel 作为一个过渡, Model 的数据获取和加工由 ViewModel 负责, 得到适合 View 的数据, 利用绑定机制, 使得 View 得以自动更新.
优点:- 层次更加分明清晰
- 代码简洁优雅
- 减少 VC 的复杂性
- 代码和界面完全分离
- 方便测试
缺点: - MVVM 需要使用数据绑定机制, 对于 os x 开发, 可以直接使用 cocoa Binding, 对于 iOS , 没有太好的数据绑定方法, 可以使用 KVO, 但是如果需要绑定的属性太多的话, 需要编写大量的 Selector 代码.
- reactiveCocoa 提供了一种很方便优雅的绑定机制.
ReactiveCocoa
- RAC 具有函数式编程和响应式鞭策的特性
- 视图解决以下问题
- 传统 iOS 开发过程中, 状态以及状态之间依赖过多的问题
- 传统 MVC 架构的问题: Controller 比较复杂, 可测试性差
- 提供统一的消息传递机制
ViewController瘦身
- 把 Data Source 和其他 Protocols 分离出来 (将 UITableView 或者 UICollectionView 的代码提取出来放在其他类中)
- 将业务逻辑移到 Model 中 (和模型有关的逻辑全部在 Model 中写)
- 把网络请求逻辑转移到 Model 层 (网络请求依靠模型)
- 把 View 代码移到 View 层 (自定义View)
项目里使用的设计模式
- 单利设计模式: UIApplication, NSUserDefaults, 是苹果封装的单利. 在项目中经常会将用户数据管理封装成一个单利类, 因此用户的信息需要全局使用.
- MVC 设计模式: 现在却大部分项目都是基于 MVC 设计模式的, 现在有一部分开发者采用 MVVM, MVP 等模式.(MVP 中的 P 即为 Presenter:作为model和view的中间人,从model层获取数据之后传给view,使得View和model没有耦合。)
- 通知(NSNotification)模式: 通知在开发是必不可少的, 对于跨模块的类交互, 需要使用通知, 对于多对多的关系, 使用通知更好的实现. (页面跳转, 夜间模式什么的)
- 工厂设计模式: 其中生成控件的 API, 都已经封装成一套, 全部是扩展的类方法, 可以简化很多代码
- KVC / KVO 设计模式: 有时候需要监听某个类属性值的变化而做出响应的变化, 当变化时, 需要更新UI显示, 这个时候使用 KVC / KVO 设计模式就很方便了
如何实现单例
- 用 GCD dispatch_one 来创建, 保证单例只会创建一次. 如果不小心销毁了, 在调用方法不会创建.
注意: 实际开发中不会去重写内存管理方法, 单例一旦创建, 整个 App 使用的过程都不会释放, 占用内存, 所以可以滥用.
网友评论