33-oc协议&代理
Posted wc&Home
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了33-oc协议&代理相关的知识,希望对你有一定的参考价值。
协议基本概念
其他语言有接口的概念,接口就是一堆方法的声明没有实现.
OC中没有接口的概念,OC中的接口就是协议.
协议Protocol是由一系列的方法声明组成的
书写协议的格式
格式:
@protocol协议名称 <NSObject>
// 方法声明列表
@end
一个类怎么遵循协议
类遵守协议格式:
@interface类名 : 父类 <协议名称1, 协议名称2,…>
@end
注意:
一个类可以遵守1个或多个协议
任何类只要遵守了Protocol,就相当于拥有了Protocol的所有方法声明
协议和继承有什么区别
继承之后默认就有实现, 而protocol只有声明没有实现
相同类型的类可以使用继承, 但是不同类型的类只能使用protocol
protocol可以用于存储方法的声明, 可以将多个类中共同的方法抽取出来, 以后让这些类遵守协议即可
协议注意事项
什么是基协议
基协议:是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。
注意:建议每个新的协议都要遵守NSObject协议
协议有哪些注意事项
协议只能声明方法, 不能声明属性
父类遵守了某个协议, 那么子类也会自动遵守这个协议
在OC中一个类可以遵守1个或多个协议注意: OC中的类只能有一个父类, 也就是说OC只有单继承
OC中的协议又可以遵守其它协议, 只要一个协议遵守了其它协议, 那么这个协议中就会自动包含其它协议的声明
协议中控制方法的能否实现的关键字是什么?各有什么作用
注意: 如果没有使用任何关键字修饰协议中的方法, 那么该方法默认就是required的
注意: @required和@optional仅仅使用程序员之间交流, 并不能严格的控制某一个遵守该协议的类必须要实现该方法, 因为即便不是实现也不会报错, 只会报一个警告
@required如果协议中的方法是@required的, 要求遵守协议的类实现@required所修饰的方法,如果没有实现该方法, 那么会报一个警告
@optional如果协议中的方法是@optional的, 遵守协议的类可选择实现@optional所修饰的方法,如果没有实现该方法, 那么不会报警告
协议应用场景
1-类型限定
什么是类型限定
类型限定就是限定一个类必须遵守某个协议
类型限定的格式
数据类型<协议名称> 变量名
@property (nonatomic, strong) Wife<WifeCondition> *wife;
类型限定有什么注意点
类型限定是写在数据类型的右边的
虽然在接受某一个对象的时候, 对这个对象进行了类型限定(限定它必须实现某个协议), 但是并不意味着这个对象就真正的实现了该方法. 所以每次在调用对象的协议方法时应该进行一次验证
if ([self.wife respondsToSelector:@selector(cooking)]) {
[self.wife cooking];
}
代理设计模式
代理模式的应用场景
代理设计模式的场合:
当对象A发生了一些行为,想告知对象B(让对象B成为对象A的代理对象)
对象B想监听对象A的一些行为(让对象B成为对象A的代理对象)
当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象)
用什么类型来接收遵守协议的代理对象
使用id类型接收代理对象
如果使用id类型来接收保姆, 如果将来换保姆了, 婴儿类不用修改代码
@property (nonatomic, strong) id<BabyProtocol> nanny;
实现代理的有哪几步?(保姆照顾婴儿吃饭睡觉)
婴儿类中
1.声明婴儿是一个类(将当前对象传出去) @class Baby;
2.定义代理协议,协议中声明代理要帮婴儿做的事 (只声明方法,将婴儿传给代理,让代理实现协议中方法,注意协议格式)
@protocol BabyDelegate <NSObject>
//喂婴儿吃饭
- (void)eat:(Baby *)baby;
//哄婴儿睡觉
- (void)sleep:(Baby *)baby;
@end
3.将代理作为属性,类型限定代理遵守协议
@property (nonatomic, weak) id <BabyDelegate> 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 <BabyDelegate>
@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, constchar * 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];
}
return0;
}
代理设计模式练习及规范
协议的编写规范:
1.一般情况下, 当前协议属于谁, 我们就将协议定义到谁的头文件中
2.协议的名称一般以它属于的那个类的类名开头, 后面跟上protocol或者delegate
3.协议中的方法名称一般以协议的名称protocol之前的作为开头
4.一般情况下协议中的方法会将触发该协议的对象传递出去
5.一般情况下一个类中的代理属于的名称叫做 delegate
6.当某一个类要成为另外一个类的代理的时候,
一般情况下在.h中用@protocol 协议名称;告诉当前类这是一个协议.
在.m中用#import真正的导入一个协议的声明
以上是关于33-oc协议&代理的主要内容,如果未能解决你的问题,请参考以下文章
【iOS】协议(Protocol)和代理(Delegate)