iOS 代理模式
一、是什么?用来干什么?
代理是iOS里面的一种设计模式,使用代理可以实现监听和传参。这种模式用于一个对象“代表”另外一个对象去做和实现一些东西。
二、谁是谁的代理?
举个简单例子,比如A控制器和B控制器,假定A控制器有某一个按钮且被点击了,这时B控制器想知道A控制器按钮被点击了,也就是B想监听A何时被点击,那么我们可以说B是A的代理。
三、实现代理步骤
1.接下面的演示都是设定了B是A的代理,为了监听A控制器里的BTN被点击了。首先我们在A控制器.h里定义一个代理属性和协议,假设A控制器名:YMView
//ID 是为了避免耦合,任何控制器都可以用这个代理,YMViewDelegate 是为了告诉代理去遵守这个协议
@property (nonatomic, weak) id<YMViewDelegate> delegate;
//写protocol协议,最好命名类名+delegate,optional是为了让这个协议方法并不强求去实现 ,YMViewDidClickedLoadBtn为协议方法。
//定义协议,建立方法,这样代理才可运用。 @protocol YMViewDelegate <NSObject> @optional - (void)YMViewDidClickedLoadBtn:(YMView *) logView; @end
上面几句在A控制器里面的代码就算把代理先设定好了。
然后在A控制器的.m文件里按钮被点击时,完成下面if判断执行代码方法
//didlog为A控制器的按钮点击方法 -(void)didlog{ //A控制器被点击,[self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]是为了检测代理控制器也就是A控制器有没有实现这个协议方法,没有就不执行括号里面的东西了。 if ([self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]) { //被点了,通知代理B调用YMViewDidClickedLoadBtn方法。 [self.delegate YMViewDidClickedLoadBtn:self]; } }
接着就是让代理控制器也就是B控制器去遵守代理协议,这里设B控制器为viewcontroller
@interface ViewController ()<YMViewDelegate>
然后让B控制器成为A的代理
YMView *ym=[[YMView alloc]init]; //设置B控制器为A控制器的代理 ym.delegate=self;
最后B控制器实现代理方法
//代理调用了代理方法 -(void)YMViewDidClickedLoadBtn:(YMView *)logView{ NSLog(@"B控制器监听到了A控制器按钮被点击"); }
四、完整代码
代码表示的是控制器当B点击了BTN跳转到A,A里面有一个按钮,A里面的按钮被点击时通知B执行代理,这里设定B控制器为viewcontroller,A控制器为YMview
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end
#import "ViewController.h" #import "YMView.h" @interface ViewController ()<YMViewDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //定义BTN为了push A控制器而已,跟代理无关 UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(200, 200, 100, 100)]; btn.backgroundColor=[UIColor grayColor]; [btn addTarget:self action:@selector(pushA) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; } -(void)pushA{ YMView *ym=[[YMView alloc]init]; //设置B控制器为A控制器的代理 ym.delegate=self; [self.navigationController pushViewController:ym animated:YES]; } //代理调用了代理方法 -(void)YMViewDidClickedLoadBtn:(YMView *)logView{ NSLog(@"B控制器监听了A控制器按钮被点击"); }
#import <UIKit/UIKit.h> @class YMView; //定义协议,建立方法,这样代理才可运用。 @protocol YMViewDelegate <NSObject> @optional - (void)YMViewDidClickedLoadBtn:(YMView *) logView; @end @interface YMView : UIViewController //设定代理属性 @property (nonatomic, weak) id<YMViewDelegate> delegate; @end
#import "YMView.h" @interface YMView () @end @implementation YMView - (void)viewDidLoad { [super viewDidLoad]; //定义BTN为了测试代理 UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; btn.backgroundColor=[UIColor grayColor]; [btn addTarget:self action:@selector(didlog) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; } -(void)didlog{ //A控制器被点击,[self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]是为了检测代理控制器也就是A控制器有没有实现这个协议方法,没有就不执行括号里面的东西了。 if ([self.delegate respondsToSelector:@selector(YMViewDidClickedLoadBtn:)]) { //通知代理调用YMViewDidClickedLoadBtn方法。 [self.delegate YMViewDidClickedLoadBtn:self]; } } @end
此部分内容暂未涉及传参