一、观察者模式
故名思意就是有一个对象在默默的看着目标对象,看它是否变化,如果变换就把变化通知给关心这个变化的对象。在iOS开发中,我们主要有两种方式来实现观察者模式:notification 和KVO;
1、通知:notification。notification实现的是一对多的信息传递,可以有多个对象收听同一个广播,收听广播的对象负责回收你的广播订阅。
//订阅广播
NSNotificationCenter * notificationCenter1 = [NSNotificationCenter defaultCenter]; [notificationCenter addObserver:self selector:@selector(update:) name:@"subjectMessage" object:nil ];
//发生变化发出通知
[notificationCenter postNotification:subjectMessage];
//回收订阅
[[NSNotificationCenter defaultCenter] removeObserver:self];
2、KVO,成为键值观察的机制,对象可以通过它得到其他对象特定属性的变更通知,NSKeyValueObserving协议是基础。它和通知的区别在于,KVO是被观察者直接向观察者发出通知,主要用来绑定特定对象的属性。
[self.hero addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
//变化后的通知内容
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{if([keyPath isEqualToString:@"name"]) {NSLog(@"赋值后--%@",self.hero.name);NSLog(@"新的值--%@",change[@"new"]);NSLog(@"以前的值--%@",change[@"old"]);
}
}
[self.hero removeObserver:self forKeyPath:@"name"];//注销观察者。
二、delegate模式
简单来说代理模式,就是把想实现的行为和对象分离开,对象把这些行为委托给其他有能力的对象,来实现自己的功能。前提是,对象要把这些希望其他对象实现的方法,用@protocal的形式声明出来。所有接受委托的的对象,也要明确的接受这个协议才可以。最常见的就是tableView的delegate和dataSource。这个太多,掠过细节。
三、MVC模式
根据功能把app中的类分为Model、View、Controller三个角色,这是iOS开发的经典模式;
模型会把任何数据的变更通知控制器,然后控制器更新视图数据。视图对象通知控制器用户的操作,控制器要么根据需要来更新模型,要么检索任何被请求的数据。
你可能在想为什么不能仅仅使用控制器,在一个类中实现视图和模型,这样貌似更加容易?
所有的这些都归结于代码关注点分离以及复用。在理想的状态下,视图应该和模型完全的分离。如果视图不依赖某个实际的模型,那么视图就可以被复用来展示不同模型的数据。
四、MVVM模式
五、单利模式
单例设计模式确保对于一个给定的类只有一个实例存在,这个实例有一个全局唯一的访问点。它通常采用懒加载的方式在第一次用到实例的时候再去创建它。
例如:[NSUserDefaults standardUserDefaults], [UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager],这是Apple系统给我提供的单例。我们也可以自己创建单例,比如视频播放器、比如账号对象、等等。
单例的要点:1、该类有且只有一个实例;2、该类必须能够自行创建实例;3、该类可以向整个系统提供这个实例。
单例的优点:提供了唯一对象,在内存中只有一个对象节约资源,提高性能。更灵活的实例化过程。
单例的缺点:单例没有抽象层,扩展很困难。单例职责过重,违背了单一职责原则。
单例的实现如下:
@implementation Singleton
static Singleton * sharedSingleton =nil;
+ (Singleton *) sharedInstance
{if(sharedSingleton ==nil) {
sharedSingleton=[[Singleton alloc] init];
}
return sharedSingleton;
}
@end
另外有一个GCD的单例方式:
static Myclass _instance;
方法一:
+(id)shareInstance{
@synchronized(self){
if(_instance == nil)
_instance = [MyClass alloc] init];
}
return _instance;
}
方法二:
+(id)shareInstance{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if(_instance == nil)
_instance = [MyClass alloc] init];
});
return _instance;
}
//重写allocWithZone,里面实现跟方法一,方法二一致就行.
+(id)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if(_instance == nil)
_instance = [MyClass alloc] init];
});
return _instance;
} 这个函数重写,否则是错误的。请读者注意。
//保证copy时相同
-(id)copyWithZone:(NSZone *)zone{
return _instance;
}
单例需要注意的是在ARC和MRC下写法有所不同
MRC下创建单例步骤一样,不过要处理一些内存管理的函数
-(id)retain{//计数器不用加1
return self ;
}
-(id)autorelease{//不需要,堆区对象才需要
return self;
}
-(oneway void)release{};
-(NSUInteger)retainCount{return UINT_MAX;}
单例的销毁:
在mrc下
+(void)attemptDealloc{
[_instance release]; //mrc 需要释放,当然你就不能重写release的方法了.
_instance = nil;
}
必须把static dispatch_once_t onceToken; 这个拿到函数体外,成为全局的
+(void)attempDealloc{
onceToken = 0; // 只有置成0,GCD才会认为它从未执行过.它默认为0.这样才能保证下次再次调用shareInstance的时候,再次创建对象.
[_instance release];
_instance = nil;
}
六、策略模式 Policy
一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
我们在验证用户输入的表单的时候,加入包括电话输入框的验证和邮件输入框的验证,这两部分的验证算法是不同的,如果把这个算法看成一个函数,他几乎有相同的输入参数和返回参数。我们可以把这个相同的函数可以抽象为基类(InputValidator)的一个方法(bool validateInput(input,error)),然后抽象出两个具体的策略类:电话验证类(PhoneValidator)和邮件验证类(EmailValidator),他们需要在各自的实现里面去复写父类的验证方法。为了能够正常的调用到验证类的验证方法,我们需要自定义一个UITextField的子类CustomTextField,其中有一个InputValidator类型的引用和一个validate方法,该方法里面调用InputValidator的验证方法,然后在textFieldDidEndEditing代理方法里面调用CustomTextField的validate方法,这样就不用我们在判断输入是否合法的时候通过if else去处理每种逻辑,而且这样做方便扩展,提高可复用性
七、工厂模式
就是类方法,创建对象更方便一些。
八、MVVM
随着现在App的功能的增加导致复杂程度的提高,我们在View Controller放的东西越来越多,许多逻辑被放在 View Controller 里。它们中的一些确实属于 View Controller,但更多的是所谓的“表示逻辑(presentation logic)”,就是那些将 Model 数据转换为 View 可以呈现的东西的事情。
MVVM的引进,不是用ViewModel来取代View Controller,而是把“表示逻辑”从View Controller中抽出来放到ViewModel中,来缓解View Controller的压力,MVVM 听起来很复杂,但它本质上就是一个精心优化的 MVC 架构,而 MVC 你早已熟悉。
在 iOS 上使用 MVVM 的动机,对我来说,无论如何,就是它能减少 View Controller 的复杂性并使得表示逻辑更易于测试。