iOS之代理/协议 @protocal

理解:

@protocal 可以定义一个协议。一个类如果使用了这个协议,那么就要按照这个协议要求的去办事。最常见的就是UITableViewDelegate、UITableViewDataSource这个两个家伙。我们的类可以使用这两个协议,并对协议定义的方法进行实现(numberOfRowsInSection, heightForRowAtIndexPath...),然后需要绑定。因为我们的类已经实现了这个这两个协议。所以我们类中的tableview可以这样绑定:

tableview.delegate = self;

tableview.dataSource = self;

接下来就有疑问了,为什么写了上面2句话,我们的tableview就可以回调我们类中实现协议的函数呢。

可以想象UITableView中是如何回调我们定义的协议函数:(大概是这样:)

[_delegate heightForRowAtIndexPath:indexPath];

[_dataSource numberOfRowInSection:section];

注:上面的_delegate,_dataSource是代表的UITableView中封装的属性(对象)。

如果写过面向对象,ios中的协议,Java中的接口的话,应该可以理解上面的代码。

它这样写就是可以实现回调。疑问解决。

为了更好地说明@protocal的意义。看一个我写的小例子。

通过一个最简单的Delegate的使用去讲述Delegate:

首先是ViewController对delegate的定义,实现。

这里是ViewControlle类的代码:

 1 #import <UIKit/UIKit.h>
 2
 3 //声明协议passValueDelegate
 4 @protocol passValueDelegate <NSObject>
 5
 6 -(void)myPassValue:(NSString*)msg;
 7 -(void)myCallback;
 8
 9 @end
10
11 //ViewController类使用上面定义的协议,并将实现协议中的两个方法
12 @interface ViewController : UIViewController<passValueDelegate>{
13
14 }
15
16 //ViewController自己保有了一个passValueDelegate的协议对象
17 //类似UITableView类中保有了两个delegate/dataSource协议对象
18 @property NSObject<passValueDelegate> *mDelegate;
19
20 -(void)callMeToDo;
21
22 @end
 1 #import "ViewController.h"
 2 #import "BViewController.h"
 3
 4 @interface ViewController ()
 5
 6 @end
 7
 8 @implementation ViewController
 9
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12
13     //写了一个按钮,点击跳转到BViewController上
14     UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 80, 50)];
15     button.layer.backgroundColor = [UIColor greenColor].CGColor;
16     [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
17     [self.view addSubview:button];
18 }
19
20 //此处是代码将会调用_mDelegate对象的实现的方法。具体可以看后面的代码。
21 -(void)callMeToDo{
22     [_mDelegate myPassValue:@"cool"];
23     [_mDelegate myCallback];
24 }
25
26 -(void)buttonPressed:(id)sender{
27     BViewController *bvc = [[BViewController alloc]init];
28     //ViewController自己实现了这个协议,
29     // 然后bvc就可以引用ViewController的对象,回调ViewContrller中实现的两个方法。
30     bvc.myDelegate =  self;
31     [self presentViewController:bvc animated:YES completion:nil];
32 }
33
34 //ViewContrller使用协议,并强制实现的2个方法
35 -(void)myPassValue:(NSString*)msg{
36     NSLog(@"%@", msg);
37 }
38
39 -(void)myCallback{
40     NSLog(@"callback call now..");
41 }
42
43 - (void)didReceiveMemoryWarning {
44     [super didReceiveMemoryWarning];
45     // Dispose of any resources that can be recreated.
46 }
47
48 @end

这里是BViewContrller类的代码:

1 #import <UIKit/UIKit.h>
2 #import "ViewController.h"
3
4 @interface BViewController : UIViewController
5
6 //保有一个使用了passValueDelegate协议的对象
7 @property NSObject<passValueDelegate> *myDelegate;
8
9 @end
 1 #import "BViewController.h"
 2
 3 @interface BViewController ()
 4
 5 @end
 6
 7 @implementation BViewController
 8
 9 - (void)viewDidLoad {
10     [super viewDidLoad];
11     // Do any additional setup after loading the view from its nib.
12 }
13
14 - (IBAction)buttonPressed:(id)sender {
15     //按钮点击,回调ViewController中实现的方法。
16     //(有点和block类似。都是可以向前回调,但是本质不同)
17     //(block是函数的引用,而协议则是对象多态的表现。)
18     [_myDelegate myCallback];
19     [_myDelegate myPassValue:@"Message from B_View_Controller"];
20
21 }
22
23 - (void)didReceiveMemoryWarning {
24     [super didReceiveMemoryWarning];
25     // Dispose of any resources that can be recreated.
26 }
27
28 @end

协议的好处是规范统一接口。如果你使用了某个协议,你一定是按照协议定义的函数接口写代码的。

这里是CViewController使用了ViewController中定义的协议,然后CViewController就要按照协议的规定,

实现协议中的两个方法。CViewController的代码如下:

1 #import <UIKit/UIKit.h>
2 #import "ViewController.h"
3
4 //使用ViewController中的协议passValueDelegate
5 @interface CViewController : UIViewController<passValueDelegate>
6
7 @end
 1 #import "CViewController.h"
 2
 3 @interface CViewController ()
 4
 5 @end
 6
 7 @implementation CViewController
 8
 9 - (void)viewDidLoad {
10     [super viewDidLoad];
11     // Do any additional setup after loading the view from its nib.
12 }
13
14 -(void)myPassValue:(NSString *)msg{
15     NSLog(@"C:%@", msg);
16 }
17
18 -(void)myCallback{
19     NSLog(@"C callback.");
20 }
21
22 - (void)didReceiveMemoryWarning {
23     [super didReceiveMemoryWarning];
24     // Dispose of any resources that can be recreated.
25 }
26
27 @end

再举一个栗子。其实跟ViewController与BViewController的代码类似。

这时是DViewController实现了passValueDelegate协议。然后让ViewController的mDelegate来保有DViewController对象,

然后ViewController调用方法,就可以在ViewController中回调DViewController中的方法。

(上面的模式是不是跟UITableView的使用过程很类似。在当前的ViewController中把tableview的代理给绑定好,

然后可以在tableview中调用当前ViewController的代理实现方法。跟上面一开始讲的疑问很类似的模型)

代码也是很类似的。如下是DViewController的代码:

1 #import <UIKit/UIKit.h>
2 #import "ViewController.h"
3
4 //使用passValueDelegate协议
5 @interface DViewController : UIViewController<passValueDelegate>
6
7 @end
 1 #import "DViewController.h"
 2
 3 @interface DViewController ()
 4
 5 @end
 6
 7 @implementation DViewController
 8
 9 - (void)viewDidLoad {
10     [super viewDidLoad];
11     // Do any additional setup after loading the view from its nib.
12 }
13
14 //既然使用了协议,就要实现协议的方法。
15 -(void)myCallback{
16     NSLog(@"this is D vc");
17 }
18
19 -(void)myPassValue:(NSString *)msg{
20     NSLog(@"i am D viewcontroller");
21 }
22
23
24 - (IBAction)buttonPress:(id)sender {
25     //点击按钮,创建ViewController(可以理解为创建一个UITableView对象)
26     ViewController* vc = [[ViewController alloc]init];
27     //绑定代理
28     vc.mDelegate = self;
29     //主动回调。(可以理解为tableview中的reload函数,主动reload)
30     [vc callMeToDo];
31     //总结上面的代码:tableview可以不用主动回调,
32     // 因为tableview是一个控件,控件是一个监听者,他可以根据点击交互来发起对协议函数的回调。
33     //上面是为了举例,所以使用了主动的回调。
34 }
35
36 - (void)didReceiveMemoryWarning {
37     [super didReceiveMemoryWarning];
38     // Dispose of any resources that can be recreated.
39 }
40
41 @end

上面的代码,已经描述了protocal的使用,以及原理。

总结:

  1。具体使用:在统一规范函数接口。所有类都需要用到功能可以使用protocal来规范统一。

    比如:人,牛,马都是动物,他们都有几个共同的特点:跑,吃,喝。

    这就是动物都拥有的功能,此时就可以使用protocal来规范统一接口。

  2。函数回调,代理。类似于block,但是跟block又有很大的差别。请求网络,获取到服务器数据后,回调到初始界面。

    此时可以让初始界面实现协议,然后让请求服务器的类保有一个初始界面的协议对象,然后当获取到数据的时候,

    服务器可以根据这个协议对象,回调初始界面实现的协议具体方法。

  protocal还有2个关键字,required  和  optional关键字。

  如果你在定义协议的函数接口时,没有写上这两个关键字的话默认是required。

  required意思是以后谁使用了这个协议,就必须要实现这个协议里面的方法,是强制的。

  optional意思是可以实现协议里面的方法,也可以不实现协议里面的方法,是可选的。

至于protocal中区分具体的代理,协议。

代理就是把事情交给别人做。我只要保有那个人的电话就行了。

A类中保有一个B的代理对象引用P,B中使用了代理P, 并实现代理的方法是doSomeThing.

A类跟B类的绑定,只需要A.P = B;即可。以后有什么事,比如:

A类某天想要B做什么事,只要这样来[P doSomeThing]。B就会把事做好。

协议就是一种规范,大家必须都要按照协议说的去做。

说白了就是跟Java接口一样的功能,抽象成高层,屏蔽差异性。然后通过持有的对象引用去调用。

很好的表现对象的特性。

时间: 2024-08-24 09:33:47

iOS之代理/协议 @protocal的相关文章

ios开发之代理&amp;&amp;协议(补充篇)

一.理解协议与代理 协议: 协议是一个方法签名的列表,在其中可以定义若干个方法.根据配置,遵守该协议的类会去实现这个协议中规定的若干个方法. 代理: 代理是一个概念,很难用一个名词去定义(如我们可以说协议其实就是一个方法列表).它更像是一种关系,我要做某一个事情,但我自己不想去做这件事,我委托其他人帮我去做这件事.这个时候,这位其他人就是我的代理. 二.协议的使用 在定义协议时,可以通过@required与@optional来配置遵守这个协议必须去实现的方法和可以选择的方法.譬如: @proto

学习IOS--分类(category)和协议Protocal的理解

1.分类(category)概念和使用 如果我们使用过C#,我们都知道,C#里面有一个叫做扩展函数的东西,可以在不继承已有类的情况下,给存在的类增加一些原本没有的接口函数,Objective-C的分类概念和这个很相似,甚至可以说是同一类型的东西,虽然不知道他们谁先谁后出现,这个东西的引入,能使得编程方面更加丰富高效. Objective-C提供了一种与众不同的方式--Category,可以动态的为已经存在的类添加新的行为.这样可以保证类的原始设计规模较小,功能增加时再逐步扩展.使用Categor

? IOS 委托和协议区别和联系 (=)

IOS 委托和协议区别和联系 (=) 上一片大致说了一下IOS上面委托和协议的区别和联系,并且举了一个简单的例子,但是例子比较简单,今天做一个用委托模拟button回调的例子. 在一个自定义View上面放一个登陆按钮,并且这个LoginView里面有一个实现ILogin的委托对象,在登陆按钮的点击事件中调用需要实现的协议函数.在一个ViewController中实现ILgin协议,并实现login方法.将自定义LoginView放到ViewController中,这时候点击button按钮,回自

iOS关于代理的理解

直接上3个图,不知道说的对不对,欢迎大神指点 iOS关于代理的理解

蛋疼的Apple IOS Push通知协议

简介 Apple Push通知机制其实很简单,就是Apple的APNs服务器做为中间人,把消息推送到对应的设备上. 一张来自Apple文档的图: 当然,示意图看起来简单,但是还有一些实际的问题. 比如,如何区分Provicer的?如何区分设备的? 简单而言,是这样的: 每个应用都有一个自己的证书(certificate),开发者可以从苹果那里获得: 应用可以到APNs服务器上注册(register),然后得到一个device_token,开发者要自己保存好,推送时就要用这个来区分不同的设备. 注

iOS UITableView代理方法详解

原 iOS UITableView代理方法详解 IOS UITableView的代理方法详解(http://my.oschina.net/u/2340880/blog/404958) 一.补充 在上一篇博客中,http://my.oschina.net/u/2340880/blog/404605,我将IOS中tableView(表视图)的一些常用方法总结了一下,这篇将tableView的代理方法作了总结,对上一篇博客进行了补充. 二.UITableViewDataSourc(数据源代理) 1.必

IOS基于XMPP协议开发--XMPPFramewok框架(一):基础知识

最近蘑菇街团队的TT的开源,使我对im产生了兴趣,然后在网上找到了XMPPFramework进行学习研究, 并写了以下系列教程供大家参考,有写的不对的地方,请大家多多包涵指正. 目录索引 IOS基于XMPP协议开发--XMPPFramewok框架(一):基础知识 IOS基于XMPP协议开发--XMPPFramewok框架(二):服务器连接 IOS基于XMPP协议开发--XMPPFramewok框架(三):用户注册 IOS基于XMPP协议开发--XMPPFramewok框架(四):用户认证 IOS

iOS delegate, 代理/委托与协议.

之前知知道iOS协议怎么写, 以为真的跟特么java接口一样, 后来发现完全不是. 首先, 说说应用场景, 就是当你要用一个程序类, 或者说逻辑类, 去控制一个storyboard里面的label, 发现如果直接用 UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];//由storyboard根据myView的storyBoardID来

iOS开发总结——协议代理的认识

1.前言 自今年5月底正式转iOS之后,天天get新技能,很多技能在脑子里回旋不吐不快,所以,写点东西整理一下.先从协议代理开始. 2.协议方法的声明 @protocol EventMenuBarDelegate <NSObject> - (void)delegateShouldDoWhenMenuButtonTapped:(UIButton *)button; @end 以上代码意思是,利用@protocol 指令声明协议名EventMenuBarDelegate,并遵从NSObject协议