`
zl4393753
  • 浏览: 332551 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

[iOS]delegate和protocol [转载]

 
阅读更多
今天上班和同事讨论工程怎么组织的时候涉及到这个话题。
iOS开发上对delegate使用广泛。
记在这里,如果有新人Google到了,希望能有点帮助。

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

protocol和java里interface的概念类似,是Objective-C语法的一部分。
定义protocol如下

@protocol ClassADelegate

- (void)methodA;
- (void)methodB;

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

函数是需要被实现的,所以如果对于class如下

@interface ClassB <ClassADelegate> {
}
@end
就叫作ClassB conform to protocol ClassADelegate,也就是说ClassB实现了这个协议,
也就是实现了这一组函数。

有了上面这个头文件,我们就可以放心作调用

ClassB *b = [[ClassB alloc] init];
[b methodA];
[b methodB];
而不用担心出现unrecognized selector sent to instance这种错误了。

所以protocol就是一组函数定义,是从类声明中剥离出来的一组定义。

id<ClassADelegate> b = ...;
[b methodA];
这种用法也常见,b是一个id类型,它知道ClassADelegate这组函数的实现。

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

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

我们也可以这样写

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

@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

- (void)doSomething {
    [self blahblah];

    [self.delegate guruguru];

    [self blahblah];
}
delegate是我们写的类,这个类如果可以被传给UITableView做为其delegate,那唯一要求,就是它实现了

- (void)guruguru;
这个方法。

如果我们把这个方法定义在一个protocol里

@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)的了。

代码最终还是给人看的,公司里尤其如此。
大家都希望对方把事情讲得清晰易懂,如果在再有两句俗语或者行话那大家就很开心了 :]
分享到:
评论

相关推荐

    ios代理协议的讲解

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

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

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

    iOS代码规范_me.docx

    比较完整的iOS开发者规范 通用命名规范(讲述命名的一些通用规范) 缩写规范(讲述常见的缩写以及缩写规范) Method命名规范(讲述方法命名的具体规范) Accessor命名规范(讲述set和get方法的命名规范) ...

    IOS代理协议示例

    对于IOS的代理模式,协议什么的,看说明是很混淆的,看代码就明了多了

    IOS开发中的设计模式汇总

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

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

    本文主要给大家介绍了iOS Swift创建代理协议的各种方式,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 假如有一个类为 LXFView,现在要为这个类创建一个代理协议,我们该如何做呢? 首先,...

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

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

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

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

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

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

    ios 动态代理

    @protocol TestDelegate -(void) logStr:(NSString *) str; ///这里写一些方法接口 @end 使用代理 @interface XMRotationChartView : UIView ///类的接口定义代理的属性,给外界赋值 @property (nonatomic, assign...

    实例讲解如何在iOS应用开发中使用设计模式中的代理模式

    那么在上面的例子中,我们即是委托人,发布的信息即协议(protocol),上面规定了派件人需要完成的事,而最后选择的快递公司也就是代理人(delegate),代理我们去派件。 类图: 根据以上类图,可以知道在代理模式...

    DTTableViewManager:面向协议的UITableView管理,由泛型和关联类型提供支持

    DTTableViewManager特征 数据模型与单元,页眉和页脚之间的强大映射系统 自动数据源和接口同步。 灵活的内存/ CoreData /领域/可变数据源存储选项 强大的编译时安全事件系统,涵盖所有UITableView委托方法 通过代码...

    IOS 照片编辑的view封装的实例详解

    IOS 照片编辑的view封装 该控件有旋转,缩放,拖动,剪裁的功能,封装成了一个ImageCropperView类 需要导入的库:QuartzCore.framework ImageCopperView.h #import @protocol ImageCropperDelegate; @interface ...

    Cocoa Fundamentals Guide

    Implementing a Delegate for a Custom Class 181 The Target-Action Mechanism 182 The Target 182 The Action 183 Target-Action in the AppKit Framework 183 Target-Action in UIKit 186 Bindings (Mac OS X) ...

    DTCollectionViewManager:面向协议的UICollectionView管理,由泛型和关联类型提供支持

    内置对iOS 14 UICollectionView.CellRegistration和内容配置的支持 统一语法要求Xcode 12+ iOS 11.0以上版本/ tvOS 11.0以上版本/ macCatalyst 13.0以上版本迅捷5.3+ 如果需要Xcode 11支持或Swift 4 ... Swift 5.2或...

    能够支持无限滚动功能

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

    自定义键盘

    @protocol BGKeyBoardDelegate @required - (void)finished; @optional - (void)calculatorInputView:(BGKeyBoard *)inputView didTapKey:(NSString *)key; - (void)calculatorInputViewDidTapBackspace:...

    LxIAPManager-swift:苹果IAP封装

    iOS 7.0用法 //First, implement LxIAPManager protocol in your class.let iapEnable = LxIAPManager.iapEnable()let transactionReceipt = LxIAPManager.transactionReceipt() LxIAPManager.defaultManager()....

    LxIAPManager:苹果IAP封装

    Minimum support iOS version: iOS 7.0 用法 // First, implement LxIAPManager protocol in your class. BOOL iapEnable = [LxIAPManager iapEnable]; NSData * transactionReceipt = [LxIAPManager ...

    支持不同View直接传递参数

    源码YRUISignal,能够很方便在不同View直接传递参数,不需要复杂的delegate函数(委托函数),可以把所有view的事件都丢给ViewController处理。开发中经常遇到类似的情况,viewController上贴了view1,view1上贴了...

Global site tag (gtag.js) - Google Analytics