-
一个Protocol是由一系列的方法声明组成的
-
类遵守协议
- 一个类可以遵守1个或多个协议
- 任何类只要遵守了Protocol,就相当于拥有了Protocol的所有方法声明
-
注意
协议不能声明成员变量,不能写实现- 只要父类遵守了某个协议,那么子类也遵守
- 协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明
@interface 类名 : 父类 <协议名称1, 协议名称2,…>
@end
基协议
-
NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
-
还有名字也叫NSObject的协议,它是一个基协议,最根本最基本的协议
-
NSObject协议中声明很多最基本的方法
- description
- retain
- release
-
建议每个新的协议都要遵守NSObject协议
@protocol SportProtocol <NSObject> // 基协议
@end
关键字
-
协议中有2个关键字可以控制方法是否要实现(默认是@required,在大多数情况下,用途在于程序员之间的交流)
- @required:这个方法必须要实现(若不实现,编译器会发出警告)
- @optional:这个方法不一定要实现
代理设计模式
-
代理设计模式的场合:
- 当对象A发生了一些行为,想告知对象B(让对象B成为对象A的代理对象)
- 对象B想监听对象A的一些行为(让对象B成为对象A的代理对象)
- 当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象)
举例:婴儿与保姆
// 协议
//1.一般情况下, 当前协议属于谁, 我们就将协议定义到谁的头文件中
#import <Foundation/Foundation.h>
@class Baby;
//2.协议的名称一般以它属于的那个类的类名开头, 后面跟上protocol或者delegate
@protocol BabyProtocol <NSObject>
//3.协议中的方法名称一般以协议的名称protocol之前的作为开头
//这里不太准确
//4.一般情况下协议中的方法会将触发该协议的对象传递出去
- (void)feedWithBaby:(Baby *)baby;
- (void)hypnosisWithBaby:(Baby *)baby;
@end
//#import "BabyProtocol.h"
@interface Baby : NSObject
// 食量
@property (nonatomic, assign) int food;
// 睡意
@property (nonatomic, assign) int drowsiness;
// 饿
- (void)hungry;
// 睡意
- (void)sleepy;
//可以将协议写在数据类型的右边, 明确的标注如果想给该变量赋值, 那么该对象必须遵守某个协议
//id,遵守该协议的对象属性可以更换
//5.一般情况下一个类中的代理属于的名称叫做 delegate
//这里方便理解
@property (nonatomic, strong) id<BabyProtocol> nanny;
@end
@implementation Baby
- (void)hungry
{
self.food -= 5;
NSLog(@"婴儿饿了");
// 通知保姆
//注意: 虽然在接受某一个对象的时候, 对这个对象进行了类型限定(限定它必须实现某个协议), 但是并不意味着这个对象就真正的实现了该方法. 所以每次在调用对象的协议方法时应该进行一次验证
if ([self.nanny respondsToSelector:@selector(feedWithBaby:)]) {
[self.nanny feedWithBaby:self];
}
}
- (void)sleepy
{
self.drowsiness += 5;
NSLog(@"婴儿困了");
// 通知保姆
if ([self.nanny respondsToSelector:@selector(hypnosisWithBaby:)]) {
[self.nanny hypnosisWithBaby:self];
}
}
@end
//保姆
//当某一个类要成为另外一个类的代理的时候,
//一般情况下在.h中用@protocol 协议名称;告诉当前类 这是一个协议.
//在.m中用#import真正的导入一个协议的声明
@protocol PersonProtocol;
@interface Nanny : NSObject <BabyProtocol>
@end
#import "Baby.h"
@implementation Nanny
- (void)feedWithBaby:(Baby *)baby
{
baby.food += 10;
NSLog(@"给婴儿喂奶, 现在的食量是%i", baby.food);
}
- (void)hypnosisWithBaby:(Baby *)baby
{
baby.drowsiness += 10;
NSLog(@"哄婴儿睡觉, 现在的睡意是%i", baby.drowsiness);
}
@end
协议的编写规范:
1.一般情况下, 当前协议属于谁, 我们就将协议定义到谁的头文件中
2.协议的名称一般以它属于的那个类的类名开头, 后面跟上protocol或者delegate
3.协议中的方法名称一般以协议的名称protocol之前的作为开头
4.一般情况下协议中的方法会将触发该协议的对象传递出去
5.一般情况下一个类中的代理属于的名称叫做 delegate 6.当某一个类要成为另外一个类的代理的时候,
一般情况下在.h中用@protocol 协议名称;告诉当前类 这是一个协议.
在.m中用#import真正的导入一个协议的声明