------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1. Protocol的概念
类似于java中的接口的作用,定义一些方法,让其他类去实现。
Protocol是一些方法的声明,一般写到一个.h的头文件中,这些方法供其他的类去遵守,如果一个类遵守了一个协议,就应该实现这个协议中定义的必须要实现的方法。
2. Protocol的使用流程
定义协议----->在类中采用指定的协议---->实现协议中的方法(方法有必须实现和选择实现两种)
3. 协议的定义
@protocol 协议名称<NSObject> 默认遵守NSObject协议
//方法声明列表
@end
注意:协议默认的要采纳NSObject的协议
4. 采纳协议
记得导入协议的头文件。
1) 类遵守协议
创建类的时候遵守某个或某几个协议
@interface 类名:父类名<协议名称1,协议名称2……>
@end
2) 协议遵守协议
某个协议也遵守某个或者某些协议,一个协议可以遵守其他多个协议
@protocol 协议名称<其他协议名称1,其他协议名称2……>
声明方法列表;
@end
5. 协议的基本使用
#import <Foundation/Foundation.h>
//协议baseProtocol
@protocol baseProtocol <NSObject>
-(void)run;
-(void)eat;
@end
//Person类遵守baseProtocol协议
#import <Foundation/Foundation.h>
//导入协议的头文件
#import "baseProtocol.h"
//遵守协议
@interface Person : NSObject<baseProtocol>
@end
#import "Person.h"
@implementation Person
//实现协议中必须要实现的方法
-(void)eat{
NSLog(@"长得漂亮又能吃,叫吃货;长得丑又能吃,叫饭桶。");
}
-(void)run{
NSLog(@"running");
}
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [Person new];
[p eat];
[p run];
}
return 0;
}
6. protocol使用注意
1) protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现。
2) 只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。
3) 只要父类遵守了某个协议,那么子类也遵守。
4) Protocol声明的方法可以让任何类去实现,protocol就是协议。
5) OC不能继承多个类(单继承),但是能够遵守多个协议。
6) 基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。
7) 协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明。
8) 协议也可以采纳其他协议
9) 类如果采纳协议后,实现了协议的方法,这些方法时可以被子类继承的。
7. Protocol基协议
NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它,它还有名字也叫NSObject的协议,它是一个基协议,最根本最基本的协议。
建议每个新的协议都要遵守NSObject协议。
8. Protocol中的@required和@optional
@required和@optional是协议方法声明中的两个关键字,它们主要用于控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流。
@protocol base<NSObject>
@required//可以省略,默认为@required,表示必须要实现的方法
-(void)run;
-(void)eat;
@optional //不能省略,表示可选择实现的方法
-(void)fly;
@end
9. Protocol类型限制
1) 使用id存储对象时,对象的类型限制
Id <协议名称>变量名
id <myProtocoll>obj
含义为定义的这个obj对象必须要遵守myProtocol协议
2) 对象赋值时的类型限制
格式:类名<协议名称>*变量名
NSObject<myProtocol>*obj
含义为定义的这个obj对象必须为NSObject类型的,而且要遵守myProtocol协议。
3) 对象关联关系下,对象的类型限制
对象A的实例变量中包含B的对象,对B进行声明时需要让B遵守一定的协议。
10. Protocol代理设计模式举例
以保姆和婴儿为例,婴儿饿了保姆要喂婴儿吃东西,婴儿困了保姆要哄婴儿睡觉。
//协议
#import <Foundation/Foundation.h>
@class Baby;
@protocol lookBabyProtocol<NSObject>
//喂婴儿吃东西
-(void)letBabyEat:(Baby *)baby;
//哄婴儿睡觉
-(void)letBabySleep:(Baby *)baby;
@end
//婴儿类
#import <Foundation/Foundation.h>
#import "lookBabyProtocol.h"
@class BaoMu;
@interface Baby : NSObject
@property (nonatomic,assign)intblood; //婴儿的体力值
@property (nonatomic,assign)intsleep; //婴儿的睡眠值
//婴儿的代理---保姆
@property (nonatomic,strong)BaoMu<lookBabyProtocol>*bm;
-(void)forEat;
-(void)forSleep;
@end
#import "Baby.h"
#import "BaoMu.h"
@implementation Baby
//婴儿想吃东西
-(void)forEat{
NSLog(@"forEat...");
[self.bm letBabyEat:self];
}
//婴儿想睡觉
-(void)forSleep{
NSLog(@"forSleep...");
[self.bm letBabySleep:self];
}
@end
//保姆类
#import <Foundation/Foundation.h>
#import "lookBabyProtocol.h"
@class Baby;
//保姆要遵守协议
@interface BaoMu :NSObject<lookBabyProtocol>
@end
#import "BaoMu.h"
#import "Baby.h"
@implementation BaoMu
//喂婴儿吃东西
-(void)letBabyEat:(Baby *)baby{
NSLog(@"baby is eating~~");
baby.blood+=10;
}
//哄婴儿睡觉
-(void)letBabySleep:(Baby *)baby{
NSLog(@"baby is sleeping~~");
baby.sleep+=15;
}
@end
//主函数
#import <Foundation/Foundation.h>
#import "Person.h"
#import "lookBabyProtocol.h"
#import "Baby.h"
#import "BaoMu.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//定义对象
Baby *baby = [Baby new];
BaoMu *baomu = [BaoMu new];
//让婴儿有一个保姆
baby.bm = baomu;
//初始化婴儿的体力值和睡眠值
baby.blood = 20;
baby.sleep = 12;
//婴儿想吃东西
[baby forEat];
//婴儿想睡觉
[baby forSleep];
NSLog(@"baby.blood = %d,baby.sleep =%d",baby.blood,baby.sleep);
}
return 0;
}
11. Protocol代理设计模式
1) 概念
传入的对象,代替当前类完成了某个功能,称为代理模式。
利用协议实现代理模式的思路:
① 定义一个协议,里面声明代理类需要实现的方法列表
② 创建一个代理类,遵守上面的代理协议
③ 在需要代理的类中,定义一个对象类型为id,且遵守代理协议的成员变量(delegate)
④ 在需要代理的类中调用成员变量(delegate)的方法,调用代理类的方法。
⑤ 在main.m或其他使用需要代理的类的文件中,为这个类的成员变量(代理类)赋值
2) 代理设计模式应用场合
① 通知的场合:当对象A发生了一些行为,想告知对象B(让对象B成为对象A的代理对象)
② 监听器场合:对象B想监听对象A的一些行为(让对象B成为对象A的代理对象)
③ 有些事情,不想自己处理,想交给别人处理
当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象)。
3) 代理模式设计,学生通过中介找房子
//创建协议
#import <Foundation/Foundation.h>
@protocol findHouseProtocol<NSObject>
-(void)findHouse;
@end
//代理类遵守协议
#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
@interface LinkHome :NSObject<findHouseProtocol>
@end
#import "LinkHome.h"
@implementation LinkHome
-(void)findHouse{
NSLog(@"链家正在帮您找房子。");
}
@end
//学生类
#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
@interface Student : NSObject
//定义一个类型为id,遵守协议的成员变量
@property (nonatomic,strong)id<findHouseProtocol>delegate;
-(void)needHouse;
@end
#import "Student.h"
@implementation Student
-(void)needHouse{
NSLog(@"学生需要找房子");
//调用成员变量(代理)的方法
[self.delegate findHouse];
}
@end
#import <Foundation/Foundation.h>
#import "findHouseProtocol.h"
#import "Student.h"
#import "LinkHome.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//创建对象
Student *stu = [Student new];
LinkHome *lh = [LinkHome new];
//给成员变量赋值
stu.delegate = lh;
[stu needHouse];
}
return 0;
}
12. @property的使用
1) 在要遵守协议的类中可以使用@property 协议名称;的格式,引入要遵守的协议,而不使用#import,这和@class作用一样,只是告诉编译器这是一个协议,但协议里面有哪些方法不知道。
2) 在遵守协议的类中使用@property后,需要再.m文件中使用#import引入协议的头文件。
3) 在main函数中,也要导入协议的头文件