委托和协议的理解
在iOS中,委托和协议承担着类似于基石的角色,目前网络上关于委托和协议的文章帖子有很多很多,但内容都是大同小异,悟性快的理解快,悟性慢的看了就是云里雾里的晕。
本篇文章从另一个角度来解释委托和协议,帮助更深入的理解委托和协议,如有错误,欢迎各位网友批评指正。
大家都非常熟悉C++ OOP的一些概念和方法技巧,所以我们从C++的角度来理解委托和协议,或许能更容易更深入的理解。
在C++ OOP中,对象之间的复用有一种方法是包含,示意如下:
class dct
{
public:
void fdct(short data[64]);
void idct(short data[64]);
};
void dct::fdct(short data[64])
{
// ....
}
void dct::idct(short data[64])
{
// ....
}
在此例中,dct类实现了快速DCT变换和快速DCT反变换。
现在需要开发一个MPEG4视频编码和解码库,需要用到快速DCT变换和快速DCT反变换,现在有了class dct,就不用去开发FDCT和IDCT的代码了,把class dct直接拿来用就好了。于是就在不严格区别public,private等权限问题和其他语法语义的情况下,示意性的写如下代码:
class codec
{
public:
short m_data8x8[64];
class dct *m_pdct;
public:
codec();
~codec();
void calc_dct();
void calc_idct();
};
codec::codec();
{
m_pdct=new class dct();
}
codec::~codec();
{
delete m_pdct;
}
void codec::calc_dct()
{
m_pdct->fdct(m_data8x8);
}
void codec::calc_idct()
{
m_pdct->idct(m_data8x8);
}
类似这样的代码我们写了很多年,基本上可以认为是小儿科的东西了,其实委托和协议和这个小儿科的东西差不多。
为了更方便的集成和互换各个厂家实现的快速DCT变换和快速DCT反变换,标准化不开避免,于是做DCT和IDCT实现的各个厂家开会讨论对外的一致接口,于是类似于下面的接口诞生了。
class dct
{
virtual void fdct(short data[64])=0;
virtual void idct(short data[64])=0;
};
厂家A实现自己的DCT模块示意如下
class A:public class dct
{
void fdct(short data[64]);
void idct(short data[64]);
}
void A::fdct(short data[64])
{
// ...
}
void A::idct(short data[64])
{
// ...
}
除去各种语言规定的语法形式和关键字有些不同外,按照iOS的观点来看这个例子,我们把定义成纯虚函数的class dct 叫做"协议",把class A叫做"委托对象",把m_pdct叫做"委托变量"。当class codec需要用到fdct和idct的时候,就通过委托变量m_pdct把计算任务委托给类似于class A这样的类来计算。
在上面这个例子中,我们按照C++的观点来看,要直观一些,就是简单的对象复用,貌似是主动调用dct()和idct()函数。当然iOS中的委托和协议可以做更多的事情,有主动调用也有被消息触发后被动调用,貌似更多的是被动调用,也为了彰显不同,就把名词"对象复用"改成"委托和协议"等等其他名词。
从汉语词语来讲,"调用"貌似要主动些要强制一些,"委托"貌似要被动些要委婉些,在各个语境中,目的可能各有不同,事情有大有小,或许还有同步异步的差别,但都是把自己做不了的事请别人来做,其实质并没有什么不同。