由delegate和dataSource所想到的
为什么要把delegate和dataSource,单独拿出来说呢?因为在笔者看来只有真正理解了这两个东西,才能谈得上去理解设计模式,去封装自己的控件!可能有人觉得这个太过夸张,不急,且听我慢慢道来。
在我们日常开发中,系统提供给我们的诸多UI控件并不能完全满足我们在项目中的需要,这个时候为了提高开发效率,常用的做法就是封装出满足于需求的控件。不知读者有没有观察总结过,但凡是稍微复杂的控件都离不开两个基本因素1.逻辑 2.数据。这两点就是我们今天的主角delegate和dataSource所要承担的工作。
这里我们先以UITableView举例,来看看delegate和dataSource都干了些什么。(只列举部分来做说明)
1. UITableViewDelegate:
//某行被点击后,tableView询问代理者要执行什么操作
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
2. UITableViewDataSource:
//告诉tableView在某个section有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
//告诉tableView在某个indexPath的cell对象是什么
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
通过观察我们不难发现
delegate 是将视图内的数据和操作等传递到外部。
dataSource 是外部将数据传递到控件内,为控件提供必要的数据源。
他们本质上其实都是代理模式,并无不同,之所以加已区分,是为了使编码更加清晰。
那么说了这么多,到底有什么用呢?
一开始笔者就说过,封装是为了提高开发效率,是为了造好一个轮子后可以随处使用。所以在封装的时候一个必然不能忽视的现实问题就是:我们封装的控件内部绝对不能有业务代码逻辑!!!它一定是个存粹的存在!但是要如何使封装控件和我们的项目发生点关系呢?这个时候就该delegate和dataSource登场了。
很多时候我们想要编码一个控件时,可能思绪很乱,难以下手。这个时候我提供一个思考方式以作参考。
第一步:这个控件需要显示哪些数据?哪些东西是灵活性很大,会在具体场景中定制的?那么将这些工作交给dataSource 。这个时候我们就可以写出dataSource的协议方法了。
第二步:我们需要这个控件如何处理业务逻辑和业务数据?那么将这些工作交给delegate。这个时候我们就可以写出delegate的协议方法了。
第三步:剩下的已经和业务无关了,我们只要存粹的去完成这个控件,并在恰当的时机调用协议方法就可以了。其实不光光是自己动手编程,在使用别人的控件时我们也可以顺着这个思路去学习如何使用。
这种编码思想在业界还有个高大上的名字,你或许听过,叫面向接口编程。对没错,它并没有很神秘和高深。笔者觉得很多知识你只有知道为什么去使用它,知道它的来龙去脉,自然就能理解它的真香,并且融会贯通。