协议是多个类共享的一个方法列表,在协议中列出的方法,在定义协议的类中并没有给出具体的实现,而协议的实现是在遵守协议的类中定义的,通过协议可以实现对象之间的通信,同时又能使类的定义更加通用。
1.为什么需要协议
协议用来解决对象之间的通信问题,特别是当视图对象向控制器对象通信(发送用户点击动作,请求设置视图数据)时常用协议。
通过协议可以进一步提升该类的通用性,例如,对于某个按钮的点击动作,在所有遵守协议的对象中,可以定义不同的动作。
协议的实现步骤
在该类.h文件中,设置类应用@class,定义协议方法及方法@protocol(第一个参数一般传自己),添加协议属性(注意使用weak属性)
.h文件中:
#import <UIKit/UIKit.h>
@class MYView;//前置声明该类
NS_ASSUME_NONNULL_BEGIN
@protocol MYViewProtoc <NSObject>//定义协议的格式
-(void)myView:(MYView *)myView clickButton:(UIButton*)button;
@end
@interface MYView : UIViewController
@property(nonatomic,weak) id<MYViewProtoc> protocol;//定义一个protocol的属性,一定要用weak,一定要用id类型,遵守协议,这个protocol将来就是遵守协议的类。
@end
NS_ASSUME_NONNULL_END
.m
-(void)clickBtn:(UIButton *)button{
//通知我们的protocol对象(可能是控制器)工作
//固定写法,判断protocol对象是否实现了d这个协议方法
if([self.protocol respondsToSelector:@selector(myView:clickButton:)]){
//如果实现了就通知protocol类去执行这个方法
[self.protocol myView:self clickButton:button];
}
}
控制器中
#import "ViewController.h"
#import "MYView.h"
@interface ViewController ()<MYViewProtoc>// 遵守协议
@property (nonatomic,strong)MYView *myView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self myView];//n懒加载要调用方法
// Do any additional setup after loading the view, typically from a nib.
}
-(MYView *)myView{
if(_myView==nil){
_myView=[[MYView alloc]init];
[_myView setFrame:CGRectMake(0, 100, 320, 50)];
[self.view addSubview:_myView];
_myView.protocol=self;//设置协议对象
}
return _myView;
}
//具体实现协议内容
- (void)myView:(MYView *)myView clickButton:(UIButton *)button{
NSLog(@"%s",__func__);
NSLog(@"%@-----%@",myView,button);
}
@end
这样MYView类可以复用。,可以把自己传递过去,所以可以实现对象间的通信。
@required和@optional
在协议当中,方法的声明,被@required修饰,那么就准守这个协议的类,必须实现这个方法,否则就会发出警告
被@optional修饰,那么准守这个协议的类,可以实现这个方法,也可以不实现这个方法,不实现编译器也不会报警告。
唯一的区别,就是当遵守协议的类,而不实现协议中的方法的时候,@required会给一个警告,@optional不会又警告的
常见的协议种类
代理delegate:常用于监控事件即将发生will,正在发生,结束发生did;
数据源datasource:设置视图的显示内容,如tableView
代码:https://github.com/ShaeZhuJiu/protocol-.git