OC第九节——协议与代理
一、理解协议与代理
协议:
协议就是需要相互遵守的约定、规范;需要去实现协议中规定的方法。
代理:
代理是一个概念,很难用一个名词去定义(如我们可以说协议其实就是一个方法列表)。它更像是一种关系,我要做某一个事情,但我自己不想去做这件事,我委托其他人帮我去做这件事。这个时候,这位其他人就是我的代理。代理模式是一种设计思想,是人们在开发过程中经验的积累与总结,他们发现,以这样的形式去写代码,会降低代码间的耦合,这样就能增加代码的重用性,就能提高开发效率,节省开发时间。
二.协议的关键词
@required:表示必须实现的方法 (默认)
@optional:表示可以实现也可以不是实现的方法
三,代理
1.1明星打官司,一般明星是不会亲自去的,一来在这样的公众场合抛头露面确实不太方便,再者就是,所谓打官司就是摆事实讲道理,别看明星台词背得很瓷实:“ 男:对,你无情你残酷你无理取闹! 女:那你就不无情!?不残酷!?不无理取闹!? 男:我哪里无情!?哪里残酷!?哪里无理取闹!? 女:你哪里不无情!?哪里不残酷!?哪里不无理取闹!? 男:我就算在怎么无情再怎么残酷再怎么无理取闹也不会比你更无情更残酷更无理取闹! 女:我会比你无情!?比你残酷!?比你无理取闹!?你才是我见过最无情最残酷最无理取闹的人! 男:哼,我绝对没你无情没你残酷没你无理取闹! 女:好,既然你说我无情我残酷我无理取闹我就无情给你看残酷给你看无理取闹给你看! 男:看吧,还说你不无情不残酷不无理取闹现在完全展现你无情残酷无理取闹的一面了吧!” what a fuck!明星自然知道,如果把这个用到官司里,估计所有人都疯了。所以,他们一般都会找(委托)一个律师去帮他处理,律师就成了这个明星的委托人。
1.2 正向代理与反向代理
请原谅我使用这两个词,但是,从理解和学习今天的知识来说,我们可以这样先这样来分一下。
明星委托律师打官司,律师并不是无偿的,他会收取明星的佣金。
我们可以这样来看,明星委托律师打官司,此时,律师是明星的代理。而律师又委托明星给他支付酬劳,明星就是律师的代理了。
如果还不好理解,我重新给大家讲这个故事。
一个人,他想赚钱,他找到一个明星,跟明星说,你是大明星,有很多钱,你能给我点嘛?(律师委托明星)明星想了想,说,这样,我现在有点小麻烦,你帮我搞定了(明星委托律师),这些就都是你的了。
这就是我所谓的正向代理与反向代理。
不过,我们也可以这样来看,把他分为两块。单看明星找律师打官司,以明星作为主视角,那么律师就是明星的代理。
再者,律师找明星弄点钱,以律师为主视角,那么明星就是律师的代理。
如果分为两块,每块的主视角不一样,则都属于正向代理了。
就像1,2,3,4,5,6,7,8,9,10 这组数,我们说是从小到大排列的。但如果是古人,他可能会说是从大到小排列的,主视角或出发点不同而已。
1.3 一般意义上的代理
目前为止,我们可以这样来理解代理,A类想要做一件事,但是A类不会做,或不直接做,而是委托B类去做。A委托B,B是A的代理。
四、代理与协议的使用
我尽可能的用代码来进行描述,但首先需要进行一些context铺垫
我想实现的功能:我要自定义一个View,这个view可能展示了我自己项目中特定的一些信息,它可能是若干控件的组合,譬如UITextField、UISwitch、UIDatePicker、balabalabala...我们姑且叫这个view为myInformationView 我在一个ViewController使用了这个view,为了方便,这个ViewController就叫myRootViewController。在使用这个myInformationView时,我需要即时的在myRootViewController获取并做相应的处理。这是我想实现的功能。
接下来,就是开始写代码的时刻:
1.首先是一个protocol
#import <Foundation/Foundation.h>
@class MyInformationView;
@protocol MyInformatioViewDelegate<NSObject>
@required
@returnValueToShow:(MyInformationView*)myInformationView;
@end
2.MyInformationView
#import <UIKit/UIKit.h>
@interface MyInformationView : UIView
@property (nonatomic, strong) id<MyInformationViewDelegate> myDelegate;
- (id)initWith......//初始化视图的方法
//所需要的属性和方法根据实际需要再行添加
@end
#import "MyInformationView.h"
@interface MyInformationView()
@end
@implementation MyInformationView
@synthesize myDelegate = _myDelegate;
//Todo: 处理一些初始化方法和其他一些事件
// changeMyInformationData 是操作此view可能产生的数据变动。它可能是选择器变动、点击按钮等等,但我们并不想在此view处理它,因为它的变动可能对调用此view的controller造成影响,所以...
- (void) changeMyInformationData:(id)sender
{
//TODO:数据变动....
if ([self.myDelegate respondsToSelector:@selector(returnValueToShow:)]) {
[self.myDelegate returnValueToShow:self];
}
}
@end
3.ViewController
这里就不写代码了,在头文件中声明此类遵守MyInformationViewDelegate协议。在实现文件(.m)中,调用MyinfomationView的时候,设置代理成自己,
MyInformation *myInfoView = [[MyInformation alloc] init.......];
myInfoView.myDelegate = self;
然后实现协议中要求实现的方法
- (void)returnValueToShow:(MyInformationView*)myInfoView
{
//TODO:做想做的事情
}
这样就是一整套完整的代理与协议组合用法了。但其实代理与协议还可以做更多的事情,例如在页面切换时(A页面进入AA页面)...通过传入,使AA成A的代理,并对其进行操作来方便处理一些问题。
简单的步骤来说:
1.在被代理的类里面创建一个协议;
//创建一个协议
@protocol secondVCDelegate <NSObject>
-(void)inputValue:(NSString *)inputValue;
@end
2.声明这个协议(声明一个delegate属性 可以用weak或者assign修饰
)
//声明一个delegate的属性,可以用weak或者assign来修饰
@property(nonatomic,weak) id<secondVCDelegate>delegate;
3.就是代理对象里面遵守这个协议
//遵守这个协议
@interface ViewController ()<secondVCDelegate>
4.实现被代理对象的方法(就是要代理对象去做啥)
/**
* 实现被代理对象的方法,将捕获的值设置到UILabel中
*
* @param inputValue 传过来的值
*/
-(void)inputValue:(NSString *)inputValue{
label.text = inputValue;
}
5. 设置被代理对象的delegate属性为代理对象(设置代理)
DelegateController *delegate = [[DelegateController alloc]init];
//设置被代理对象的delegate属性为代理对象即self
delegate.delegate = self;
[self.navigationController pushViewController:delegate animated:YES];
6.首先判断代理人是否存在,其次判断代理人是否实现了代理方法,如果都做了,就让代理人去执行代理方法
//4、调用代理对象完成传值
if (self.delegate && [self.delegate respondsToSelector:@selector(inputValue:)]) {
//让代理执行代理方法
[self.delegate inputValue:texfile.text];
}
[self.navigationController popViewControllerAnimated:YES];
以上就是协议与代理的基本用法。