protocol和delegate

protocol和delegate完全不是一回事,放在一起说,只是因为我们经常在同一个头文件里看到这两个word。

protocol和java里interface的概念类似,是Objective-C语法的一部分。
定义protocol如下

1
2
3
4
@protocol ClassADelegate
- ( void )methodA;
- ( void )methodB;
@end

那么就是定义了一组函数,这组函数放在一起叫作一个protocol,也就是协议。

函数是需要被实现的,所以如果对于class如下

1
2
3
4
@interface ClassB<ClassADelegate>
{
}
@end

就叫作ClassB conform to protocol ClassADelegate,也就是说ClassB实现了这个协议,
也就是实现了这一组函数。

有了上面这个头文件,我们就可以放心作调用

1
2
3
ClassB *b = [[ClassB alloc] init];
[b methodA];
[b methodB];

而不用担心出现unrecognized selector sent to instance这种错误了。

所以protocol就是一组函数定义,是从类声明中剥离出来的一组定义。

1
2
id &lt;ClassADelegate&gt; b = ...;
[b methodA];

这种用法也常见,b是一个id类型,它知道ClassADelegate这组函数的实现。

那么delegate是什么?其实和protocol没有关系。Delegate本身应该称为一种设计模式。
是把一个类自己需要做的一部分事情,让另一个类(也可以就是自己本身)来完成。
比如ClassC

1
2
3
4
5
@interface ClassC
{
    id delegate;
}
@end

那么ClassC的实现(.m文件)里就可以用delegate这个变量了。
当然这里完全可以用其它名字而不是delegate。

我们也可以这样写

1
2
3
4
5
@interface ClassC
{
    ClassB *delegate;
}
@end

这样我们知道了delegate是一个ClassB,它就可以提供ClassB里的方法。
可以把一部分ClassC里的工作放在ClassB里去实现。
这样的写法看起来是不是有点奇怪?或者应该写成这样?

1
2
3
4
5
@interface ClassC
{
    ClassB *classB;
}
@end

delegate没有了…
所以说其实delegate只是一种模式,大家约定俗成,当把自己内部一部分实现暴露给另外一个类去做的时候,就叫实际做事的类为delegate。

为什么会需要把内部实现提出来给另一个类做呢?
最常见的目的就是为了在隐藏实现的前提下,提供一个自定义的机会。
比如Apple提供的iOS SDK里就有众多的delegate,比如最常用的UITableView,
我们没法知道Apple怎么重用UITableViewCell,怎么处理UITableView里Cell的增加、删减,因为我们没有源码。
但是我们可以通过实现Delegate的方法来控制一个UITableView的一些行为。
UITableViewDataSource其实和delegate是一样一样的,只是由于意义不同换了个名字罢了。

protocol在此扮演了什么角色呢?
protocol是一种语法,它提供了一个很方便的、实现delegate模式的机会。
比如写UITableView的时候,Apple这么干
UITableView.m

1
2
3
4
5
6
- ( void )doSomething
{
    [ self blahblah];
    [ self .delegate guruguru];
    [ self blahblah];
}

delegate是我们写的类,这个类如果可以被传给UITableView做为其delegate,那唯一要求,就是它实现了

1
- ( void )guruguru;

这个方法。

如果我们把这个方法定义在一个protocol里

1
2
3
@protocol XXXProtocol
- ( void )guruguru;
@end

就说明了,UITableView需要的delegate是一个conform to XXXProtocol的类。
这就正好是

id
表达的意思。
无论具体的类是什么,它还有其它什么方法,只要它conform to这个protocol,
就说明它可以被传给UITableView,作为它的delegate。
那么Apple为了让我们知道这个protocol是delegate需要conform的protocol,
它就把XXXProtocol改成了UITableViewDelegate

这样我们看到protocol的名字里有Delegate,就知道这个protocol里的函数是用来做自定义(Customization)的了。

代码最终还是给人看的,公司里尤其如此。
大家都希望对方把事情讲得清晰易懂,如果在再有两句俗语或者行话那大家就很开心了 :]

回答: 在iOS开发中,可以使用Block和delegate来实现一对多的回调。使用delegate时,首先需要定义一个delegate协议,其中包含回调方法。然后在需要进行回调的地方,设置delegate并调用回调方法。具体实现可以参考以下代码示例:\[2\] ``` // 定义delegate协议 protocol FirstCellDelegate: class { func firstCellBtnTap(_ cell: firstTableViewCell) } // 在需要进行回调的地方设置delegate并调用回调方法 weak var delegate: FirstCellDelegate? // 调用回调方法 if let delegate = self.delegate { delegate.firstCellBtnTap(self) } // 实现delegate回调方法 func firstCellBtnTap(_ cell: firstTableViewCell) { let cellIndexPath = tableView.indexPath(for: cell) print("delegate回调 section:\(cellIndexPath?.section ?? 0), row:\(cellIndexPath?.row ?? 0)") } ``` 另外,使用Block也可以实现一对多的回调。Block可以作为函数表达式传递给API,可以选择性地存储,并且可以被多个线程使用。Block不仅包含了在回调时需要执行的代码,还包含了执行期间所需的数据。具体实现可以参考以下代码示例:\[3\] ``` // 定义Block回调 typealias CallbackBlock = () -> Void // 在需要进行回调的地方使用Block进行回调 var callback: CallbackBlock? // 调用回调 callback?() ``` 通过使用Block和delegate,可以实现一对多的回调,满足不同场景下的需求。 #### 引用[.reference_title] - *1* [Block实现iOS回调](https://blog.csdn.net/feelinghappy/article/details/119870367)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [iOS Block与Delegate的用法,各自优缺点及使用场景](https://blog.csdn.net/huangshanfeng/article/details/82106580)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值