objective-c中协议protocol的理解

     一个协议就是一份承包合同,合同是签约双方的一个约定,它规定了双方应尽的义务。签合同分为三个部分:雇主、承包商、合同。而一个协议的完成也需要三个部分:协议protocol、协议使用方某类、协议实现方delegate。

     1.  雇主是受服务者,他只需要知道是谁在帮自己干活儿,不需要知道承包商是怎么具体完成的(不要做豆腐渣工程)。这就是类中声明的id<yourDelegate> _delegate。
     2.  承包商需要完成合同中规定的任务,任务分为必须完成的任务和可选的任务,好比咱们的午饭,必须有米饭,但菜有哪几样是可选的。在协议中,定义在@optional下的方法为可选方法,而非optional方法则必须全部实现。
      3. 合同本身并不专属于某个雇主或者某个承包商,只要它是一份成熟的、合理的合同,可以有很多雇主和承包商使用,因此合同的一个重要部分是指明雇主和承包商身份。
      类比一下协议protocol,一个protocol不独属于某个类classA,classA、classB中都使用UITableView(NSTableView同理),它们都使用UITableViewDataSource协议,而classA、classB、classC都实现了这个协议。那么classA的tableView该去找谁取自己的数据呢?这就需要setDelegate,假设classA中的tableView实例为roomListTableView,[roomListTableView setDelegate:classC]就指定了去classC中取数据。
    4. 在订立好合同后,在某个时刻,作为雇主的你打电话给承包商说:可以开工了。OK,一切都运转起来了。这就是最终的使用委托方法。
---------------------------------------------------------------------------------------------------------------------------------------------------
    这里有几点需要注意:
    1.  协议本身是独立于任何类的,定义一个协议后可以由任何类使用,也可以由任何类实现。比如“干洗店”,它只是一个名称,而实际生活中,可以有很多人开“干洗店”,也会有很多人去“干洗店”洗衣服。有的时候把一个协议和某个类的头文件写在一起,只是因为协议的
方法较少,写在使用这个协议的类的头文件里会方便查找,其实你完全可以把协议单独写在一个文件里。
    2.  协议的使用和实现可以在同一个类内,比如常用的tableView,都是在同一个类内使用和实现dataSource协议。
  
    3.  协议不能拆分来实现。举个例子:一个雇主可以指定承包商A盖房子1,指定承包商B盖房子2;但是不能让承包商A去盖房子1的1楼,让承包商B去盖房子1的2楼。举个更贴切的例子:你可以把两条裤子拿去不同的干洗店清洗,但不可能把一条裤子的左腿拿去“老江干洗店”洗,然后拿右腿去“老字号干洗店”清洗。也就是说,每个delegate都必须是完整实现的,需要把所有的非optional方法实现。
       因此,需要分开来做的事情,要单独写protocol。对于一个特定的协议如buildingDelegate,也只能指定单一的delegate [classA setBuildingDelegate:classB]。
    4.  协议之间互不影响,classA可以指定classB做protocol1、protocol2,等等。
 
    5.  不同的类可以指定同一个协议的同一个委托方,classA和classB都可以指定classC做protocol1,这时只需要在protocol1的实现方法内识别不同对象,分别处理。
    6.  使用协议很重要的一步,是你要在需要的时刻去调用委托方法。当然,TableView这种内置控件的委托方法是自动调用的。
    7.  这个合同是个不平等条约,雇主不会承诺做任何事情。因此,使用协议的一方是不需要做什么特定工作的。
    8.  可以用一个变量指定多个协议,id<protocol1,protocol2,...> myDelegate,这个变量将限制可以调用那些delegate方法,超出中括号中协议范围的方法不可以被myDelegate调用。(如果一定要调用协议外的方法,那就相当于在使用对象变量直接调用方法,而不是在使用协议)
     
    9.  在程序中见到一种写法,比如classA中有id delegate变量,现在[classA setDelegate:classB],然后用来在classA中调用classB的方法如[delegate addSubview:self],其实这不是协议,只是一个用了delegate名字的普通对象指针。如果classA和classB相互包含,两个类互相调用是一件危险的事情,确认你知道自己在做什么。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值