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真正的导入一个协议的声明

 

posted @ 2016-03-04 20:48  wc&Home  阅读(355)  评论(0编辑  收藏  举报