iOS 设计模式知多少

什么是设计模式
设计模式是为特定场景下的问题定制的解决方案,设计模式分三种类型:创建型,结构型,行为型.这里只列举iOS常用到的几种:

创建型 : 单例 , 工厂
结构型 : 代理 , MVC
行为型 : 观察者 , 策略

单例模式
单例类 : 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例

优点:
1-节省内存
每次获取实例时会先进行判断,实例存在则返回,否则创建实例,如果一直不用,则不会创建实例,从而节省了内内存空间

2-因为单例类控制实例化过程,所以可以更灵活的修改实例化过程

缺点:
1-运行费时间
上面的判断会浪费一些时间

2-线程安全问题
并发情况下,如果线程A和线程B同时调用某一方法,会创建出两个实例,此时单例模式失效,若想解决线程安全问题,需要加synchronized解决,但会降低访问速度

使用场景:
1-如果创建某一个对象会耗费很多系统资源,此时采取单例模式,因为只需要一个实例,会节省alloc时间

2-若很多模块需要使用同一变量,可以将它放入单例类

3-实际应用:”我的音乐”项目中 “音乐播放器/列表管理/文件管理”均为单例模式

代理模式

当一个类的某些功能(协议)需要由别的类来实现,但是又不确定具体会是哪个类实现,本质是某个类持有了另一个类的指针
协议是约束一个类必须实现某些方法
协议中只能定义方法,不能定义成员变量,属性,@required为必须实现的,@optional为可选择实现的
因为协议这个接口和类并不存在关联关系,所以我们要用到代理,声明一个代理属性,约定实现代理的对象去实现协议方法
说起来有点绕,但理解了就好了….

优点:
1-有利于代码的封装
2-有利于程序的结构化和层次化
3-若是@required的方法,没有实现会编译警告/报错
4-一个类可以定义不同的协议,当然,每个协议得对应不同的delegate

缺点:
1-代码量多,协议定义,delegate属性,本身决定什么时候执行代理,实现代理类的实现

2-释放后,delegate要为nil,否则会是野指针,造成内存泄漏,这也是要用weak来声明delegate的原因

3-只能一对一通信,不过这个好像不算是缺点
备注:
-假如现在有类A,类B,类C
-类C协议为CDelegate,点击类C的按钮时,相应协议,输出一句话
-类A和类B都实现了方法
-执行的操作是,从类A跳转到类B,从类B跳转至类C,点击类C的按钮,只有类B相应了

使用场景:
tableView的Cell内按钮点击时
音乐播放器当前歌曲的进度
……

实现过程:
举例:类A实现了类B的协议
类B
1.声明协议及协议方法,这是要让别的类,比如“A”实现的

2.声明此协议的代理对象,谁使用了这个代理对象,谁就实现上面的协议,比如“A”

3.本类决定了,实现我代理对象的类,比如“A”,何时实现我的协议方法,例当我点击我本身的按钮时实现

类A
1.声明”B”对象,并实现”B”协议的代理

2.实现协议方法,何时实现由”B”控制

拿tableView的cell内按钮点击举例

111602974-88c561073190a05d

 121602974-85cfadb98294c63d

扩展一:运行时机制
假如我们上面不用代理实现,改成如下依然可以实现:

扩展二
1-代理用weak,不用assign的原因
assign和weak均是指针赋值(直接赋值),不改变索引计数,但当被销毁时,
assign:如果使用完毕,不将其置为nil,会产生野指针,操作不当会崩溃
weak:在属性所指的对象遭到摧毁时,属性值也会清空(nil out),不会崩溃

假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a 和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉

2- assigin可以用非 OC 对象,而 weak 必须用于 OC 对象

3- 代理用weak,不用strong的原因,是因为防止循环引用

观察者模式

观察者模式是一种通知变化的模式,分下面两种

  • Notification
    优点:
    1-代码量少,实现简单
    2-对于一个发出的通知,多个对象能够做出反应,即一对多
    缺点:
    1-释放通知对象时,需要在通知中心移除注册
    2-观察者需要提前知道通知的名字,如果未定义,会不同步
    3-编译器不会检查通知是否能被观察者处理(相对比delegate)
  • KVO
    优点:
    1-简单
    2-能够对非我们创建的对象,即内部对象的状态改变做出相应
    3-用key path观察属性,因此也可以观察嵌套对象
    4-也可以一对多
    缺点:
    1-观察的属性必须使用NSString定义
  • Delegate,NSNotification,KVO
    1-三者均是类和类之间的通信
    2-NSNotification和KVO一对多,Delegate一对一
    3-NSNotification和KVO不关心接受者的态度,意思就是发出通知后剩下的事就不管了,而delegate会关注结果

NSNotification例子(带参数)

KVO会单开专题讲解

MVC模式
Model-View-Controller的缩写,是一种架构模式,讲的是M和V的代码分离,通过数据模型,控制器逻辑,视图展示将应用程序进行逻辑划分。

优点:
1-层次清晰,代码简洁
2-方便测试及改动,易于维护
缺点:
1-增加系统结构和实现的复杂性
2-视图对模型数据低效率访问

这个就不举例子了.

工厂模式

简单工厂模式: 为了向客户提供方便,将分配和初始化合在一个步骤中,返回被创建的对象.说白了,就是对象的封装.
优点:客户端直接使用产品,而不用关心产品的具体实现
缺点:工厂类负责逻辑实现,一旦出现问题,均受影响,而且,每增加一个产品,就要增加一个工厂类
使用场景:多个地方用到某一对象,并且此对象属性一样时

简单工厂模式例子:
每个应用程序都会有自己的主色调,字体颜色及大小等等吧,我们定义每一个Button时,若都写给它设置颜色,字体,字号等太麻烦,可以封装起来,这样声明一个Button只需要执行一句代码就行啦

131602974-14a956f96c3ad768

类工厂模式:大致可以理解为,通过继承,创建不同的对象
优点:方便替换
缺点:不能算缺点,只是创建的这些类是同一个父类
使用场景:若使用时类会有变动,比如后台若传你不同的数据,需要建不同的类,可以考虑用这个

再举一个例子,假如后台返回的数据有不同的类型,根据传来的key值不同返回不同的对象

策略模式
和工厂模式相比,策略模式是对算法的封装,使算法可以互相替换.

之前看过一个例子,假如你出去旅游,有多种方案选择,可以骑自行车,汽车,火车,飞机,每个策略都可以得到相同的结果,但使用的是不同的资源

有一篇讲策略模式很好的文章,推荐一下
设计模式之策略模式(iOS开发,代码用Objective-C展示)

1 3 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部