1.什么是设计模式?
在计算机编程语言中有32种设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样,在iOS中常用的实际模式为:代理模式,MVC模式,MVVC模式,单例模式等。
2. 代理设计模式是iOS开发中非常重要的一种设计模式,在UI中用的最多.
其应用场景:
> 当对象A无法处理某些行为的时候,想让B对象帮助处理(B对象成为A对象的代理)
> 当对象A发生一些行为,想通知对象B来解决(B对象成为A对象的代理)
> 当对象A想监听对象B的一些变化(A对象成为B对象的代理)
3. 如果想成为某个对象的代理,且必须遵守某个对象所指定的协议.帮助这个对象处理协议中的行为.
比如.
学生找房子,学生会找一个中介,让他来帮忙找房子,这个中介就是一个代理.且这个代理要遵守一定的协议,
这个中介一定要具备帮学生找房子的行为.
再比如婴儿和保姆的例子,婴儿需要照顾,可以找一个保姆来照顾婴儿,这个保姆要具备这样的协议,喂孩子喝奶,哄孩子睡觉等行为.这样保姆就成为了婴儿的代理.
4. 好了话不多少,直接上代码.(婴儿和保姆为例)
注意: 这里为了代码看着直观,我把每个类的.h和.m文件合并在一起了.在开发中一般都是多文件开发!
Baby文件:
#import
@class Baby,Nanny;
@protocol babyProtocol
// 喂孩子吃东西
- (void) babyFeedFood : (Baby *)baby;
// 哄孩子睡觉
- (void) babyHongSleep : (Baby *)baby;
@end
@interface Baby : NSObject
// 饥饿值
@property (nonatomic, assign) int hungry;
// 睡意值
@property (nonatomic, assign) int sleep;
// 吃东西
- (void) eatFood;
// 困了
- (void) sleepy;
// 为婴儿找一个代理
@property (nonatomic, weak) id delegate;
@end
@implementation Baby
- (void)eatFood
{
self.hungry += 5;
NSLog(@"baby: 宝宝饿了要吃东西! 饥饿值 = %i",_hungry);
// 判断保姆是否实现了协议中的方法
if ([self.delegate respondsToSelector:@selector(babyFeedFood:)]) {
[self.delegate babyFeedFood:self];
}
}
- (void)sleepy
{
self.sleep = 3;
NSLog(@"baby: 宝宝困了要睡觉! 睡意值 = %i",_sleep);
if ([self.delegate respondsToSelector:@selector(babyHongSleep:)]) {
[self.delegate babyHongSleep:self];
}
}
@end
Nanny文件:
#import "Nanny.h"
#import "Baby.h"
@implementation Nanny
// 实现协议中的方法
- (void)babyFeedFood:(Baby *)baby
{
baby.hungry -= 5;
NSLog(@"delegate: 别哭了,喂你喝奶! 饥饿值 = %i",baby.hungry);
}
- (void)babyHongSleep:(Baby *)baby
{
baby.sleep += 15;
NSLog(@"delegate: 别哭了,哄你睡觉! 睡意值 = %i",baby.sleep);
}
@end
#import "Nanny.h"
#import "Baby.h"
@implementation Nanny
// 实现协议中的方法
- (void)babyFeedFood:(Baby *)baby
{
baby.hungry -= 5;
NSLog(@"delegate: 别哭了,喂你喝奶! 饥饿值 = %i",baby.hungry);
}
- (void)babyHongSleep:(Baby *)baby
{
baby.sleep += 15;
NSLog(@"delegate: 别哭了,哄你睡觉! 睡意值 = %i",baby.sleep);
}
@end
main文件.
#import
#import "Baby.h"
#import "Nanny.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
// 创建一个婴儿
Baby *baby = [[Baby alloc] init];
// 创建一个保姆
Nanny *nanny = [[Nanny alloc] init];
baby.delegate = nanny;
// Student *stu = [[Student alloc] init];
// baby.delegate = stu;
[baby eatFood];
[baby sleepy];
return 0;
}
输出结果:
2017-07-31 12:51:17.398101+0800 婴儿和保姆代码优化[1843:63899] baby: 宝宝饿了要吃东西! 饥饿值 = 5
2017-07-31 12:51:17.398352+0800 婴儿和保姆代码优化[1843:63899] delegate: 别哭了,喂你喝奶! 饥饿值 = 0
2017-07-31 12:51:17.398377+0800 婴儿和保姆代码优化[1843:63899] baby: 宝宝困了要睡觉! 睡意值 = 3
2017-07-31 12:51:17.398413+0800 婴儿和保姆代码优化[1843:63899] delegate: 别哭了,哄你睡觉! 睡意值 = 18
总结:
协议的编写规范:
1. 一般情况下,当前协议属于谁,我们就讲协议定义到谁的头文件中
2. 协议的名称一般以它属于的那个类的类名开头,后面跟上protocol 或者 delegate
3. 协议中的方法起名: 一般以写明名称protocol或delegate之前的作为开头
4. 一般情况下协议中的方法会将触发该协议的对象传递出去
5. 一个类的代理名称叫delegate.(见名知意)
6. 当某一个类要称为另一个类的代理的时候,一般情况下,
在.h文件中使用@protocol 协议名称; 告诉当前类,这是一个协议,并遵守它.
在.m文件中使用 #import 真正的导入一个协议的声明