array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 委托和协议的理解 - 爱码网

                   委托和协议的理解

在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,就不用去开发FDCTIDCT的代码了,把class dct直接拿来用就好了。于是就在不严格区别publicprivate等权限问题和其他语法语义的情况下,示意性的写如下代码:

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反变换,标准化不开避免,于是做DCTIDCT实现的各个厂家开会讨论对外的一致接口,于是类似于下面的接口诞生了。

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需要用到fdctidct的时候,就通过委托变量m_pdct把计算任务委托给类似于class A这样的类来计算。

在上面这个例子中,我们按照C++的观点来看,要直观一些,就是简单的对象复用,貌似是主动调用dct()idct()函数。当然iOS中的委托和协议可以做更多的事情,有主动调用也有被消息触发后被动调用,貌似更多的是被动调用,也为了彰显不同,就把名词"对象复用"改成"委托和协议"等等其他名词。

从汉语词语来讲,"调用"貌似要主动些要强制一些,"委托"貌似要被动些要委婉些,在各个语境中,目的可能各有不同,事情有大有小,或许还有同步异步的差别,但都是把自己做不了的事请别人来做,其实质并没有什么不同。

相关文章: