博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
协议和代理
阅读量:5333 次
发布时间:2019-06-15

本文共 3480 字,大约阅读时间需要 11 分钟。

1.协议基本概念

什么是协议?

  • 其他语言有接口的概念,接口就是一堆方法的声明没有实现.
  • OC中没有接口的概念,OC中的接口就是协议.
  • 协议Protocol是由一系列的方法声明组成的

书写协议的格式?

格式:

@protocol 协议名称 
// 方法声明列表@end

 

 

一个类怎么遵循协议?

 

类遵守协议格式:

@interface 类名 : 父类 <协议名称1, 协议名称2,…>

@end

注意:

  1. 一个类可以遵守1个或多个协议
  2. 任何类只要遵守了Protocol,就相当于拥有了Protocol的所有方法声明

协议和继承区别

  1. 继承之后默认就有实现, 而protocol只有声明没有实现
  2. 相同类型的类可以使用继承, 但是不同类型的类只能使用protocol
  3. protocol可以用于存储方法的声明, 可以将多个类中共同的方法抽取出来, 以后让这些类遵守协议即可

2.协议注意事项

什么是基协议?

  • 基协议:是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。
  • 注意:建议每个新的协议都要遵守NSObject协议

协议有哪些注意事项?

  1. 协议只能声明方法, 不能声明属性
  2. 父类遵守了某个协议, 那么子类也会自动遵守这个协议
  3. 在OC中一个类可以遵守1个或多个协议 注意: OC中的类只能有一个父类, 也就是说OC只有单继承
  4. OC中的协议又可以遵守其它协议, 只要一个协议遵守了其它协议, 那么这个协议中就会自动包含其它协议的声明

协议中控制方法的能否实现的关键字是什么?各有什么作用?

  1. 注意: 如果没有使用任何关键字修饰协议中的方法, 那么该方法默认就是required的
  2. 注意: @required和@optional仅仅使用程序员之间交流, 并不能严格的控制某一个遵守该协议的类必须要实现该方法, 因为即便不是实现也不会报错, 只会报一个警告
  3. @required 如果协议中的方法是@required的, 要求遵守协议的类实现@required所修饰的方法,如果没有实现该方法, 那么会报一个警告
  4. @optional 如果协议中的方法是@optional的, 遵守协议的类可选择实现@optional所修饰的方法,如果没有实现该方法, 那么不会报警告

 

3.协议应用场景1-类型限定

问题1:什么是类型限定?

答:类型限定就是限定一个类必须遵守某个协议

问题2:类型限定的格式?

答: 数据类型<协议名称> 变量名

 

@property (nonatomic, strong) Wife
*wife;

 

 

 

类型限定注意点

  1. 类型限定是写在数据类型的右边的
  2. 虽然在接受某一个对象的时候, 对这个对象进行了类型限定(限定它必须实现某个协议), 但是并不意味着这个对象就真正的实现了该方法. 所以每次在调用对象的协议方法时应该进行一次验证
if ([self.wife respondsToSelector:@selector(cooking)]) {[self.wife cooking];}

 

 

代理模式的应用场景?

1.当A对象想监听B对象的一些变化时, 可以使用代理设计模式 保姆想监听婴儿的变化, 那么保姆就可以成为婴儿的代理, 当婴儿发生变化之后保姆就可以监听到

2.当B对象发生一些事情, 想通知A对象的时候, 可以使用代理设计模式 婴儿想通知保姆, 那么就可以 让保姆成为婴儿的代理, 只要保姆成为婴儿的代理, 以后婴儿发生变化就可以通知保姆

3.当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象) 婴儿无法自己吃东西, 也无法自己入睡, 所以可以让保姆帮忙处理. 只要让保姆成为婴儿的代理就可以帮婴儿喂它吃东西和哄他睡觉

 

用什么类型来接收遵守协议的代理对象?

使用id类型接收代理对象

// 如果使用id类型来接收保姆, 如果将来换保姆了, 婴儿类不用修改代码

@property (nonatomic, strong) id
nanny;

 

 

 

问题3:实现代理的有哪几步?(保姆照顾婴儿 吃饭 睡觉)

答:

婴儿类中

1.声明婴儿是一个类(将当前对象传出去) @class Baby;

2.定义代理协议,协议中声明代理要帮婴儿做的事 (只声明方法,将婴儿传给代理,让代理实现协议中方法,注意协议格式)

@protocol BabyDelegate 
//喂婴儿吃饭- (void)eat:(Baby *)baby;//哄婴儿睡觉- (void)sleep:(Baby *)baby;@end

 

 

3.将代理作为属性,类型限定代理遵守协议

 

@property (nonatomic, weak) id 
delegate;

 

 

 

4.声明方法,方法里调用代理,调用代理实现的协议方法,让代理帮婴儿吃饭,睡觉

//婴儿饿了要吃饭- (void)hurgry;//婴儿醒了要睡觉- (void)wake;

 

 

5.实现调用代理者的方法

@implementation Baby- (void)hurgry{//    6.判断代理是否实现了协议中的方法    if ([self.delegate respondsToSelector:@selector(eat:)]) {        //7.如果代理实现了协议中的方法,就调用        [self.delegate eat:self];    }}- (void)wake{    if ([self.delegate respondsToSelector:@selector(sleep:)]) {        [self.delegate sleep:self];    }}@end

 

 

代理类中

8.导入代理

 

@protocol BabyDelegate;

 

 

 

9.遵守代理

@interface Nurse : NSObject 
@end

 

 

10.实现协议中的方法,(喂婴儿,让婴儿吃饭,拿到婴儿才能给婴儿做事)

@implementation Nurse- (void)eat:(Baby *)baby{    baby.hurgryValue += 10;    NSLog(@"喂婴儿吃饭!饥饿值:%lu", baby.hurgryValue);}- (void)sleep:(Baby *)baby{    baby.sleepValue += 5;NSLog(@"摇婴儿睡觉!疲劳值:%lu", baby.sleepValue);}@end

 

 

main函数中

int main(int argc, const char * argv[]) {    @autoreleasepool {//11.创建所需对象        Baby *b = [[Baby alloc]init];        Nurse *n = [[Nurse alloc]init];//12.将代理对象作为接受代理者的代理        //(让保姆作为婴儿的代理)        b.delegate = n;//设定婴儿初始饥饿值,疲劳值        b.hurgryValue = -5;        b.sleepValue = -5;//13.接受代理者调用代理者的方法        //(婴儿饿了,醒了,需要吃饭和哄一哄)        [b hurgry];        [b wake];    }    return 0;}

 

5.代理设计模式练习及规范

协议的编写规范

  1. 一般情况下, 当前协议属于谁, 我们就将协议定义到谁的头文件中
  2. 协议的名称一般以它属于的那个类的类名开头, 后面跟上protocol或者delegate
  3. 协议中的方法名称一般以协议的名称protocol之前的作为开头
  4. 一般情况下协议中的方法会将触发该协议的对象传递出去
  5. 一般情况下一个类中的代理属于的名称叫做 delegate
  6. 当某一个类要成为另外一个类的代理的时候, 一般情况下在.h中用@protocol 协议名称;告诉当前类 这是一个协议. 在.m中用#import真正的导入一个协议的声明

 

转载于:https://www.cnblogs.com/dreamWanweidong/p/4997973.html

你可能感兴趣的文章
posix多线程有感--线程高级编程(线程属性函数总结)(代码)
查看>>
DCDC(4.5V to 23V -3.3V)
查看>>
kettle导数到user_用于left join_20160928
查看>>
activity 保存数据
查看>>
typescript深copy和浅copy
查看>>
linux下的静态库与动态库详解
查看>>
hbuilder调底层运用,多张图片上传
查看>>
较快的maven的settings.xml文件
查看>>
Git之初体验 持续更新
查看>>
随手练——HDU 5015 矩阵快速幂
查看>>
Maven之setting.xml配置文件详解
查看>>
SDK目录结构
查看>>
malloc() & free()
查看>>
HDU 2063 过山车
查看>>
高精度1--加法
查看>>
String比较
查看>>
Django之Models
查看>>
CSS 透明度级别 及 背景透明
查看>>
Linux 的 date 日期的使用
查看>>
PHP zip压缩文件及解压
查看>>