Objective-C 中的协议(Protocol)

特点

  • 不同的类实现相似的功能
  • 不同的类之间互相不干扰

声明

可以声明类方法、实例方法以及属性。

例如:

@protocol XYZPieChartViewDataSource

- (NSUInteger)numberOfSegments;
- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;

@end

协议可以被任意对象实现,因此如果要声明一个协议对象,类型应当设置为id

@interface XYZPieChartView : UIView

@property (weak) id <XYZPieChartViewDataSource> dataSource;

...

@end

Objective-C 使用尖括号表示某个类实现了某个协议;同时作为一个类的属性时,协议对象应当被标记为 weak,以防止循环引用导致的内存泄露。

默认情况下,在协议中声明的方法是 必须实现的,这意味着任何声明了协议的对象都必须实现协议中声明的方法或属性。

通过 @ required 指令,在它之后声明的方法或属性为 必须实现

协议支持 可选 的方法或属性

通过 @optional 指令,在它之后声明的方法或属性为 可选

如下表所示:

@protocol XYZPieChartViewDataSource

- (NSUInteger)numberOfSegments;
- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;

@optional
- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;
- (BOOL)shouldExplodeSegmentAtIndex:(NSUInteger)segmentIndex;

@required
- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex;

@end

在代码运行时需要判断 可选 的方法或函数是否被实现

NSString *thisSegmentTitle;
if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) {
        thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];
    }

继承自其他协议的协议对象

  • 协议可以继承另外一个协议
  • 当声明一个协议时,它默认会继承 NSObject 协议
  • 实现某个协议的对象,需要同时实现这个协议和它的父协议
@protocol MyProtocol <NSObject>

...

@end

MyProtocol 协议继承自 NSObject 协议

实现它的类不但需要实现 MyProtocol 协议,也要实现 NSObject 协议

遵照协议

一个类要遵照某个(某些)协议,写法如下:

@interface MyClass : NSObject <MyProtocol, AnotherProtocol, YetAnotherProtocol>

...

@end

一般情况下,某个类需要实现的协议不会太多

如果一个类中实现了过多的协议,则需要考虑重构它,把这个类拆分为多个类,分别实现不同的协议

同时一个协议也不宜实现过多的功能,实际应用中,需要将一个大的协议尽量拆解成多个协议来实现多种功能

协议是匿名使用的

可以不需要知道某个实例是哪种类型,而调用协议方法

id <XYZFrameworkUtility> utility = 
[frameworkObject anonymousUtility];

NSUInteger count = [utility numberOfSegments];

另一个 CoreData 的例子:

NSInteger sectionNumber = ...
id <NSFetchedResultsSectionInfo> sectionInfo = 
[self.fetchedResultsController.sections objectAtIndex:sectionNumber];

NSInteger numberOfRowsInSection = [sectionInfo numberOfObjects];

参考资料

Working with Protocols

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,392评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,258评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,417评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,992评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,930评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,199评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,652评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,327评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,463评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,382评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,432评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,118评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,704评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,787评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,999评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,476评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,057评论 2 341