什么是设计模式
设计模式是为特定场景下的问题定制的解决方案,设计模式分三种类型:创建型,结构型,行为型.这里只列举iOS常用到的几种:
创建型 : 单例 , 工厂
结构型 : 代理 , MVC
行为型 : 观察者 , 策略
单例模式
单例类 : 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例
优点:
1-节省内存
每次获取实例时会先进行判断,实例存在则返回,否则创建实例,如果一直不用,则不会创建实例,从而节省了内内存空间
2-因为单例类控制实例化过程,所以可以更灵活的修改实例化过程
缺点:
1-运行费时间
上面的判断会浪费一些时间
2-线程安全问题
并发情况下,如果线程A和线程B同时调用某一方法,会创建出两个实例,此时单例模式失效,若想解决线程安全问题,需要加synchronized解决,但会降低访问速度
使用场景:
1-如果创建某一个对象会耗费很多系统资源,此时采取单例模式,因为只需要一个实例,会节省alloc时间
2-若很多模块需要使用同一变量,可以将它放入单例类
3-实际应用:”我的音乐”项目中 “音乐播放器/列表管理/文件管理”均为单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
1.定义 + (instancetype)defaultManager { static 单例类名 *instance = nil; static dispatch_once_t onceToken; dispatch_once( &onceToken, ^{ instance = [[self alloc] init]; }); return instance; } 2.使用 [单例类名 defaultManager]调用方法及属性即可 3.注意 假如我们令 _yourList = [CCListManager defaultManager].defaultList; 若你对_yourList执行移除操作 [_yourList removeObjectAtIndex:indexPath.row]; 则单例类中的defaultList此行也被移除了 |
代理模式
当一个类的某些功能(协议)需要由别的类来实现,但是又不确定具体会是哪个类实现,本质是某个类持有了另一个类的指针
协议是约束一个类必须实现某些方法
协议中只能定义方法,不能定义成员变量,属性,@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”实现的
1 2 3 |
@protocol BDelegate - (void)passValue: (NSString *)string; @end |
2.声明此协议的代理对象,谁使用了这个代理对象,谁就实现上面的协议,比如“A”
1 |
@property(nonatomic,assign)id delegate; |
3.本类决定了,实现我代理对象的类,比如“A”,何时实现我的协议方法,例当我点击我本身的按钮时实现
1 2 3 4 |
-(void)onClick { [self.delegate passValue:@"少壮不努力,老大徒伤悲啊”]; } |
类A
1.声明”B”对象,并实现”B”协议的代理
1 2 |
BViewController *b = [[BViewController alloc] init]; b.delegate = self; |
2.实现协议方法,何时实现由”B”控制
1 2 3 4 |
- (void)passValue:(NSString *)string { NSLog(@"代理传给了我什么%@",string); } |
拿tableView的cell内按钮点击举例
1 2 3 4 5 6 7 8 9
优点: 2-因为单例类控制实例化过程,所以可以更灵活的修改实例化过程 缺点: 2-线程安全问题 使用场景: 2-若很多模块需要使用同一变量,可以将它放入单例类 3-实际应用:”我的音乐”项目中 “音乐播放器/列表管理/文件管理”均为单例模式
当一个类的某些功能(协议)需要由别的类来实现,但是又不确定具体会是哪个类实现,本质是某个类持有了另一个类的指针 优点: 缺点: 2-释放后,delegate要为nil,否则会是野指针,造成内存泄漏,这也是要用weak来声明delegate的原因 3-只能一对一通信,不过这个好像不算是缺点 使用场景: 实现过程:
2.声明此协议的代理对象,谁使用了这个代理对象,谁就实现上面的协议,比如“A”
3.本类决定了,实现我代理对象的类,比如“A”,何时实现我的协议方法,例当我点击我本身的按钮时实现
类A
2.实现协议方法,何时实现由”B”控制
拿tableView的cell内按钮点击举例 |