如何用简单明了的话解释一下什么是 Objective-C 中的委托?

感觉无论是看书还是网上搜索,都不能完全弄明白什么是委托。是函数指针?还是什么?在StackOverFlow上看了半天,依然弄不懂。不知道知乎里有没有高…
关注者
272
被浏览
60,148
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

2016年10月更新:关于委托在iOS开发中的“位置”,可以参考下图


及我写的博文:《

iOS中的「回调(callback)」

--------------------------------------------------------------------------------------------------------------


一开始我对Delegation也是云里雾里。经过一段时间实践和浸淫,有了些许理解,分享如下,感觉比较适合初学者。个人见解,欢迎指正谬误。

先举个例子:

·假设你的软件有一个表格(UITableView)界面,当你点击了表格中的某行(cell),这个表格就说:“点我干嘛?我负责显示而已,其他事不关我的事。一边凉快去!”。不过,这个表格看到你猛搓屏幕、欲哭无泪的可怜样子,于是心软了,决定帮帮你。表格就拜托(委托)它的一个朋友帮忙,名字挺洋气的,叫“UITableViewController”(以下简称C),C就很仗义地帮忙了,当你再点击的时候,C就利用tableView: didSelectRowAtIndexPath:方法,让你点击了表格后,有了相关的反馈(比如跳入下一页)。

以上——“表格”委托“UITableViewController”处理点击事件。这就是“委托/ Delegation”,它就是一种思想,一种思路,一种“设计模式”。

扩展1:为什么要用这种思想?

·就我的理解,为了贯彻MVC这种设计模式。什么?不知道MVC?那“分工合作”总该理解吧。

·继续上面的例子,表格(UITableView)为了更好、更专业地开展工作,它就计划着一门心思呆在显示界面这个岗位上,其他事情它不管。但是,软件的使用者是和界面直接打交道的,我点击你这个表格,你总要给我点反应吧?于是,很善长逻辑思维的UITableViewController就把这活儿接过来,专门从事软件的逻辑部分工作。这样“分工合作”,以后我们干什么活,就知道该找谁了。

·这样分工合作后,你也可以直接把这个表格拖到其他程序,继续使用。(提高了重用性)。

所以,“委托”的使用,是为了分工、为了降低程序的耦合性、为了重用。用它就对了,我们可是站在伟人的肩膀上。

扩展2:我怎么知道可以委托谁?

·上面例子中,表格委托了它朋友“C”办事,那在实际写代码中,我怎么知道要委托谁,或者怎么判断谁有能力帮上忙?

·这就涉及到“协议/Protocol”了,“C”能帮忙,是因为它遵守了<UITableViewDelegate>这个协议,换句话说,只要遵守了<UITableViewDelegate>这个协议,阿猫阿狗(任何类)都能帮忙,都可以完成这个任工作。

·那我怎么知道谁遵守了,谁没遵守协议?其实,控制权在你手中,你想让谁遵守都可以(只需在类名后的尖括号写上协议名称即可)——注意:“任何类都可以声明自身实现某个协议”(出处:维基百科)。(上面例子UITableViewController这个类,是系统自带的类,苹果把它搞出来的时候就遵守了<UITableViewDelegate>协议,天生就有能力帮忙。)

·另外,子类继承父类,同时也继承父类遵守的协议。比如,我创建一个新类,继承的是“UITableViewController”这个类,那我创建的这个新类,并不用手动添加<UITableViewDelegate>协议,也同样具备能力协助表格处理点击事件。

扩展3:协议/Protocol

·现在大家知道“协议/Protocol”的作用没?它可以让你的小弟(你的类)拥有某种能力、变得三头六臂、无所不能。

·协议的本质,是一个方法列表(里面的方法还没实现,等着你实现),协议中的方法分两种,分别用@required和@optional标记。标记了@required的方法,是“被委托对象"(UITableViewController)一定要实现的方法,不实现会报错;标记了@optional的方法,可以选择性实现。

·如果方法什么都没标记,默认代表是@required方法。

·如果现在还有人教你:协议分两种,一种正式协议、一种非正式协议,那建议你把这个人拖出去枪毙三分钟。苹果2006年发布的Objective-C 2.0”中,引入上述的@optional关键字后,就废弃了“非正式协议”,现在只有“协议/ Protocol”一种。(出处:维基百科)

扩展4:“委托/ Delegation”与“协议/Protocol”的关系

·通过上面,你应该了解“委托”和“协议”的大概关系了吧。要使用“委托”这种设计模式,就要用到“协议”,让被委托的对象(类)具备相应能力胜任工作。他俩是形影不离的了。