一、 简单使用
1. 基本用途
Ø 可以用来声明一大堆方法(不能声明成员变量)
Ø 只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明
Ø 只要父类遵守了某个协议,就相当于子类也遵守了
2. 格式
Ø 协议的编写
@protocol 协议名称
// 方法声明列表
@end
Ø 某个类遵守协议
@interface 类名 : 父类 <协议名称>
@end
3. 关键字
协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
Ø @required:这个方法必须要实现(若不实现,编译器会发出警告)
Ø @optional:这个方法不一定要实现
4. 协议遵守协议
Ø 一个协议可以遵守其他多个协议,多个协议之间用逗号 , 隔开
Ø 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
@protocol 协议名称 <协议1, 协议2>
@end
5. 基协议
Ø NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
Ø 其实还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
Ø NSObject协议中声明很多最基本的方法,比如description、retain、release等
Ø 建议每个新的协议都要遵守NSObject协议
6. 定义变量时指定协议
// NSObject类型的对象,并且要遵守NSCopying协议
NSObject<NSCopying> *obj;
// 任何OC对象,并且要遵守NSCoding协议
id<NSCoding> obj2;
二、 代理设计模式
1. 设计原理
Ø 有些麻烦的事情不想自己亲自做,就可以找个人帮忙做,即交给代理对象去做
2. 设计原则
Ø 首先得拥有某个代理对象属性
Ø 其次要很清楚代理有哪些方法
Ø 最后要保证能解耦
3. 实现方案
Ø 定义一个protocol,在其中声明一些和代理沟通的方法
Ø 拥有一个代理属性id<protocol> delegate
Ø 让代理遵守protocol
有一个Baby类,有Cry行为(方法,意为“哭”),Baby可以配一个保姆,但是作为保姆,必须遵守保姆协议:能够处理Baby类Cry的行为。请根据以上描述设计一套代理设计模式
Baby.h
#import <Foundation/Foundation.h>
//导入协议头文件
#import "nannyLookAfter.h"
//声明Baby类
@interface Baby : NSObject
//声明代理类属性类型为nannyLookAfter,名称为delegate_nanny
@property id<nannyLookAfter>delegate_nanny;
//声明Baby cry函数
-(void)cry;
@end
Baby.m
#import "Baby.h"
//Baby类的实现
@implementation Baby
//实例方法cry函数的实现
-(void)cry
{
//输出提示,小孩哭的行为
NSLog(@"Baby Cry.....");
//遵守协议,处理Baby类Cry的行为
[_delegate_nanny lookAfter];
}
@end
nannyLookAfter.h
#import <Foundation/Foundation.h>
//创建协议,名为nannyLookAfter
@protocol nannyLookAfter <NSObject>
//声明协议的方法,默认为必须实现的
@required //必须实现的方法
-(void)lookAfter;
@optional //可选实现的方法
@end
Nanny.h
#import <Foundation/Foundation.h>
//声明保姆类
#include "nannyLookAfter.h"
//保姆类遵守nannyLookAfter协议,
//格式为:@interface Person:NSObject<AnimalDelegate>
@interface Nanny : NSObject<nannyLookAfter>
@end
Nanny.m
#import "Nanny.h"
//实现保姆类
@implementation Nanny
//实现保姆类所遵守协议中的方法,不需要在本类中声明
-(void)lookAfter
{
//输出提示,实现的时协议中的方法
NSLog(@"Nanny Look After Baby.not Cry!!!");
}
@end
main,m
#import <Foundation/Foundation.h>
#import "Baby.h"
#include "Nanny.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
//实例化Baby对象
Baby *baby =[Baby new];
//实例化Nanny对象
Nanny *nanny = [Nanny new];
//将保姆交给小孩的照顾
baby.delegate_nanny = nanny;
//小孩哭的时候,调用方法cry
[baby cry];
}
//程序正常退出.
return 0;
}
/*
知识点:
协议注意的地方:
(1)一个协议可以扩展自另一个协议,例如上面AnimalDelegate就扩展自NSObject,如果需要扩展多个协议中间使用逗号分隔
(2)和其他高级语言中接口不同的是协议中定义的方法不一定是必须实现的,我们可以通过关键字进行@required和@optional进行设置,如果不设置则默认是@required(注意ObjC是弱语法,即使不实现必选方法编译运行也不会报错);
(3)协议通过<>进行实现,一个类可以同时实现多个协议,中间通过逗号分隔;
(4)协议的实现只能在类的声明上,不能放到类的实现上(也就是说必须写成@interface Person:NSObject<AnimalDelegate>而不能写成@implementation Person<AnimalDelegate>);
(5)协议中不能定义属性、成员变量等,只能定义方法;
(6)使用respondsToSelector方法可以判断一个对象是否实现了某个方法
*/