代理的认识
代理是一种设计模式,代理类代理委托类实现某些功能。
代理的本质是:委托类在调用方法时委托一个ID指针弱引用的一个代理对象去发送消息
组成:
协议: 规定消息的内容
委托类: 委托者是想要实现功能的类,只要调用代理类的代理方法传入参数即可
代理类: 完成委托方的需求,真正实现功能的类
说明:
- 委托方请求代理方完成某些功能
- 代理方执行完功能后返回处理结果给委托方
- 这样外部看起来是委托方实现的功能,其实是代理方真正实现的。
- 委托的功能通过协议来规定。
具体使用
下面通过代理实现猫代理狗实现eatFood方法
协议:
WYEatFood协议有一个功能就是eatFood.
@protocol WYEatFood <NSObject>
- (void)eatFood;
@end
委托类:
在委托类中做了三件事:
- 设置代理属性,用以获取代理对象
- 在具体的方法实现中先判断代理对象是否有该方法的实现
- 如果有,则通过代理对象进行方法调用
下面代码中将WYDog的eatFood方法委托给delegate去执行。
@interface WYDog : NSObject<WYEatFood>
//设置代理对象,delegate就是遵守了WYEatFood协议的一个对象
@property (nonatomic, weak) id<WYEatFood> delegate;
@end
/*
WYDog作为委托类,它的eatFood方法委托给WYcat来执行。
*/
@implementation WYDog
//让代理对象delegate来执行eatFood方法
- (void)eatFood{
//在执行前先判断是否存在该方法
if ([self.delegate respondsToSelector:@selector(eatFood)]) {
[self.delegate eatFood];
}
}
@end
代理类:
@interface WYCat : NSObject<WYEatFood>
@end
@implementation WYCat
- (void)eatFood{
NSLog(@"猫吃鱼");
}
@end
说明:
- 代理类中对eatFood方法进行具体的实现
- 代理类中也需要遵守WYEatFood协议。
调用
- (void)viewDidLoad {
[super viewDidLoad];
WYDog *dog = [WYDog alloc];
WYCat *cat = [WYCat alloc];
dog.delegate = cat;
[dog eatFood];
}
运行结果:
2021-11-12 21:26:48.258351+0800 代理学习[19924:153821] 猫吃鱼
说明:
- dog执行eatFood方法,其结果为"猫吃鱼",说明其实是cat执行的。
- 我们通过将cat赋值给dog的delegate就做到了WYCat类代理WYDog类
注意:
- 要使用weak来修饰代理属性,因为如果委托类的代理属性强引用了代理对象,而代理对象内部又强引用了委托类的对象,就会造成循环引用
- 不能使用assign,因为它在被对象释放掉之后,不会自动的将指针指向nil,就成野指针了,而weak会自动的将指针指向nil
总结:
- 代理的本质是委托类在调用方法时通过一个ID指针弱引用的一个代理对象去发送消息
- 我们在委托类设置代理对象后,实际上只是用一个遵守某一个协议的id类型指针将代理对象进行了一个弱引用,这样任何遵守了该协议的对象都可以作为代理
- 委托方让代理执行操作,实际上就是让代理对象直接调用该方法。
网友评论