`
longtianye
  • 浏览: 2903 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

delegate和protocol

阅读更多
protocol和delegate完全不是一回事,放在一起说,只是因为我们经常在同一个头文件里看到这两个word。

协议(protocol),就是使用了这个协议后就要按照这个协议来办事,协议要求实现的方法就一定要实现。

委托(delegate),顾名思义就是委托别人办事,就是当 一件事情发生后,自己不处理,让别人来处理。

举个浅显的例子:
           我上班的工作主要内容包括 (1)写代码(2)写文档(3)测试程序(4)接电话(5)会见客户
(1)(2)我自己全权负责,但是后面(3)(4)(5)我不想或者不方便自己做,所以我想找个助手(delegate)帮我做这些事,于是我定了一个招聘要求(Protocol),里写明我的助手需要会做(3)(4)(5)这三件事。很快,我招到一个助手。
        即:我.delegate = 助手;
于是以后每当我遇到需要测试程序或者接电话的活,我就把他转交给助手(delegate)去处理,助手处理完后如果有处理结果(返回值)助手会告诉我,也许我会拿来用。如果不需要或者没有结果,我就接着做下面的事。。

protocol和java里interface的概念类似,是Objective-C语法的一部分。
定义protocol如下
C代码 
@protocol ClassADelegate 
  
- (void)methodA; 
- (void)methodB; 
  
@end 

那么就是定义了一组函数,这组函数放在一起叫作一个protocol,也就是协议。

函数是需要被实现的,所以如果对于class如下
C代码 
@interface ClassB <ClassADelegate> { 

@end 

就叫作ClassB conform to protocol ClassADelegate,也就是说ClassB实现了这个协议,
也就是实现了这一组函数。

有了上面这个头文件,我们就可以放心作调用
C代码 
ClassB *b = [[ClassB alloc] init]; 
[b methodA]; 
[b methodB]; 

而不用担心出现unrecognized selector sent to instance这种错误了。

所以protocol就是一组函数定义,是从类声明中剥离出来的一组定义。
C代码 
id<ClassADelegate> b = ...; 
[b methodA]; 

这种用法也常见,b是一个id类型,它知道ClassADelegate这组函数的实现。

那么delegate是什么?其实和protocol没有关系。Delegate本身应该称为一种设计模式。
是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。
比如ClassC
C代码 
@interface ClassC { 
    id delegate; 

@end 

那么ClassC的实现(.m文件)里就可以用delegate这个变量了。
当然这里完全可以用其它名字而不是delegate。

我们也可以这样写
C代码 
@interface ClassC { 
    ClassB *delegate; 

@end 

这样我们知道了delegate是一个ClassB,它就可以提供ClassB里的方法。
可以把一部分ClassC里的工作放在ClassB里去实现。
这样的写法看起来是不是有点奇怪?或者应该写成这样?
C代码 
@interface ClassC { 
    ClassB *classB; 

@end 
… 

delegate没有了…
所以说其实delegate只是一种模式,大家约定俗成,当把自己内部一部分实现暴露给另外一个类去做的时候,就叫实际做事的类为delegate。

为什么会需要把内部实现提出来给另一个类做呢?
最常见的目的就是为了在隐藏实现的前提下,提供一个自定义的机会。
比如Apple提供的iOS SDK里就有众多的delegate,比如最常用的UITableView,
我们没法知道Apple怎么重用UITableViewCell,怎么处理UITableView里Cell的增加、删减,因为我们没有源码。
但是我们可以通过实现Delegate的方法来控制一个UITableView的一些行为。
UITableViewDataSource其实和delegate是一样一样的,只是由于意义不同换了个名字罢了。

protocol在此扮演了什么角色呢?
protocol是一种语法,它提供了一个很方便的、实现delegate模式的机会。
比如写UITableView的时候,Apple这么干

UITableView.m
C代码 
- (void)doSomething { 
    [self blahblah]; 
  
    [self.delegate guruguru]; 
  
    [self blahblah]; 


delegate是我们写的类,这个类如果可以被传给UITableView做为其delegate,那唯一要求,就是它实现了
- (void)guruguru;
这个方法。

如果我们把这个方法定义在一个protocol里
C代码 
@protocol XXXProtocol 
  
- (void)guruguru; 
  
@end 

就说明了,UITableView需要的delegate是一个conform to XXXProtocol的类。
这就正好是

id<XXXProtocol>
表达的意思。
无论具体的类是什么,它还有其它什么方法,只要它conform to这个protocol,
就说明它可以被传给UITableView,作为它的delegate。

那么Apple为了让我们知道这个protocol是delegate需要conform的protocol,
它就把XXXProtocol改成了UITableViewDelegate

这样我们看到protocol的名字里有Delegate,就知道这个protocol里的函数是用来做自定义(Customization)的了。


来源:http://haoxiang.org/2011/08/ios-delegate-and-protocol/


Protocol 的其它问题

1. 使用时为什么要加上 iOS.delegate = self
物件名称.delegate = self,是在採用任何协定时 一定会看到的一行程式码,由于定义协定的类别并不需要实作协定内的方法,因为实作的部份是由採纳协定的类别来实作,但是它又必须要知道是由哪一个类别来实作,因此我们必须要把採纳协定类别的 instance 交给定义协定的类别,让它来使用。
另一方面并不是任何类别都可以将 instance 传给定义协定的类别来使用,其原因是,我们在定义此协定的类别里有宣告 delegate 变数时,有限定它必须要採纳此协定(id delegate)如果没有採用该协定就将 instance 传给定义该协定的类别,Xcode 同样会发出警告讯息。

2. 为什么协定的生效位置不能写在建构式中
协定的生效位置写在建构式中,并不会造成程式编译上的任何问题,因为这是属于逻辑上的错误,协定要正常生效它必须要知道实作它方法的类别的 instance,如果将生效的位置写在建构式中,在建立定义此协定的形态的变物件时,它的确会去触发此协定内的方法,但是由于并没有给它实作此协定方法类别的 instance,因此不会有任何效果产生,反之,如果一定要将生效的位置写在建构式中,那么在初始化时就必须要设定好 delegate 才行,也就是使用初始化的方法函式里还必须要带入一个参数物件好指定给 delegate。

3. 在定义协定时同时也可以採用其他的协定
如果在定义协定时同时又採用其他的协定,这会导致之后採纳此协定的类别,它必须同时实作出两个协定内的方法,同样地,你也可以利用此方式来扩充那些已经存在的协定。
C代码 
@protocol FurnaceDelegate <其它可能的协定名称> 

4. 使用 @optional 提供选择性的实作
@optional,如同它字面上的意义,在 @optional 之后的方法都可以是选择性的实作,在定义协定时使用此方法,可以让之后採纳此协定的类别不一定要完全实作出协定内的所有方法。
C代码 
@protocol FurnaceDelegate  
- (void)whenCalledDelegeteFunction; 
 
@optional 
-(void)optionalDelegeteFunction; 
 
@end 

来源:http://furnacedigital.blogspot.com/2012/01/protocol.html

来源
http://justcoding.iteye.com/blog/1453902
分享到:
评论

相关推荐

    ios代理协议的讲解

    ios中非常重要的delegate和protocol的通俗讲解,非常清晰易懂,看了之后,让你对代理和协议有不一样的认识。

    协议与委托 (Protocol and Delegate) 实例解析demo

    正式协议是通过protocol指定的一系列方法的声明,然后由实现该协议的类自己去实现这些方法。而非正式协议是通过向NSObject中添加一个类别来实现,然后子类去继承NSObject。其实都差不多。 不过,非正式协议已经渐渐...

    protocol 和 delegate

    NULL 博文链接:https://luckfox.iteye.com/blog/1826184

    UIApplicationDelegate_Protocol

    The UIApplicationDelegate protocol declares methods that are implemented by the delegate of the singleton UIApplication object. These methods provide you with information about key events in an ...

    iOS 中KVC、KVO、NSNotification、delegate 总结及区别

    iOS 中KVC、KVO、NSNotification、delegate 总结及区别  1、KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属性。而不是通过调用Setter、Getter方法访问。KVO 就是基于 KVC ...

    iOS Swift创建代理协议的多种方式示例

    首先,代理协议的命名方式:类名 + Delegatev protocol LXFViewDelegate { func view(_ view: LXFView) } 当我们创建的协议遵守其它协议的情况下,只是这样写并不会报错,接下来我们在LXFView中添加一个代理属性...

    iOS代码规范_me.docx

    Delegate方法命名规范(讲述delegate方法的命名规范) Private方法命名规范(讲述私有方法的命名规范) Category命名规范(讲述分类的命名规范) Class命名规范(讲述类命名规范) Protocol命名规范(讲述协议...

    Object-C语言教程&案例,要点难点,代码示例,代码解析

    Objective-C教程要点 ...协议与代理:理解协议(Protocol)和代理(Delegate)设计模式在Objective-C中的应用。 块与闭包:学习如何使用块(Block)实现闭包(Closure)功能。 多线程与并发:了解GCD(Grand Central Dispa

    IOS开发中的设计模式汇总

    实例:tableview的 数据源delegate,通过和protocol的配合,完成委托诉求。 列表row个数delegate 自定义的delegate (二)观察者模式 应用场景:一般为model层对,controller和view进行的通知方式,不关心谁去接收,...

    UI界面之间的值传递-思路2-微变化

    使用kvo,protocol,delegate,NSnotifaction,SignLeton实现界面之间的传值

    破解Objective-C面试:笑到最后的技术攻略!.zip

    技术关键词:Objective-C、iOS开发、Mac OS X、编程语言、面向对象编程、内存管理、自动引用计数(ARC)、协议(protocol)、类扩展(category)、键值观察(KVO)、键值编码(KVC)、Block、Delegate模式、多态性、...

    DZAppDelegate:由App Delegate处理的常见任务抽象为更简单的子类模式

    目的:DZAppDelegate将一些常用任务抽象为Subclass-protocol样式的实现,从而使开始新项目更容易,更快捷。 配置 该协议定义了以下5种可选方法: - (NSDictionary *)appDefaults; - (void)setupAppearance; - ...

    分页效果设置

    @protocol ZSegmentedControlDelegate - (void)setSelectedIndex:(NSUInteger)selectedIndex; @end typedef NS_ENUM(NSInteger, MSegmentedControlIndicatorStyle){ MSegmentedControlIndicatorStyleDefault };...

    JQuery_1.4_API开发手册

    (Bug) Fixed an issue where host and protocol were not compared case-insensitively when determining whether anAJAXrequest was local or remote (#6908) (Bug) Fixed an issue where the “clone” variable...

    jQuery最新1.4.4精简版+1.4中文手册

    (Bug) Fixed an issue where host and protocol were not compared case-insensitively when determining whether anAJAXrequest was local or remote (#6908) (Bug) Fixed an issue where the “clone” variable ...

    基于iOS的音乐播放器设计与实现

    数据库:coreData 客户端: 1. 三方库:AVPlayer播放,AFNetWorking下载,SDWebImage图片,Masonry...2. 基础知识:Objective-C语法,UI相关基本使用,Protocol,Delegate,KVO,Block 3. 其他操作:文件操作,内存管理

    【IOS一气呵成】之IAP集成:内购和内购恢复 DEMO

    @protocol RMIAPHelperDelegate //购买 -(void)requestProduct:(RMIAPHelper*)sender start:(SKProductsRequest*)request; -(void)requestProduct:(RMIAPHelper*)sender received:(SKProductsRequest*)request; -...

    能够支持无限滚动功能

    该源码是一个能够支持无限滚动功能,源码LTInfiniteScrollView,LTInfiniteScrollView能够无限滚动,可以设定视图出现的数量,总数量,...其中在delegate方法中,可以自己写不同的视图变换。 更详细的例子请参考Demo.

    LCNetwork:基于AFNetworking的网络库封装

    LC网络基于AFNetworking的封装,参考了的实现方式,接口类采用@protocol约束,接口类的创建和使用更清晰。已适配AFNetworking 3.x若遇到Demo闪退问题,请删除APP重新运行,另外感谢提供免费的测试接口。功能支持...

    http长轮询技术comet的实现

    通过comet实现了一个聊天功能。 1.需要在tomcat的server.xml里面配置 &lt;Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" ...&lt;Loader delegate="true"/&gt;

Global site tag (gtag.js) - Google Analytics