Swift与Objective-C中的Protocol
利用Protocol,我们可以在Objc和Swift实现多继承。实现方式有区别,但是道理是一样的
可以这样声明Protocol:
Objective-C
1 | @protocol SomeProtocol <NSObject> |
Swift
1 | protocol SomeProtocol |
实现Protocol:
Objective-C
1 | @interface MyClass : NSObject<SomeProtocol> |
Swift
1 | class MyClass: NSObject, SomeProtocol |
利用Protocol实现代理模式
通过代理模式可以实现方法的回调
一个例子模拟计算机启动并检测计算机的启动状态,先定义一个Protocol,
如果要定义像oc中的可选(Optional)的方法,必须在定义的时候在protocol前面加上@objc属性
1 | protocol ComupterDelegate { |
下面是个Computer类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Computer {
weak var delegate: ComupterDelegate? //可能为空所以定义为可选类型
func configureComputer(){
//计算机初始化的操作
}
func startUp(){
configureComputer()
//完成初始化,执行回调
if let delegateUW = delegate {
delegateUW.computerDidStart?()
}
}
}
然后在我们的ViewController就可以用了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class ViewController: UIViewController,ComupterDelegate {
var computer : Computer!
override func viewDidLoad() {
super.viewDidLoad()
computer = Computer()
computer.delegate = self
computer.startUp()
}
func computerDidStart() {
//此处进行计算机完成初始化后的操作
}
}
protocol实现tablecell对不同Model的适配
- 原理:protocol是一种类型,可以被用作参数,返回值,变量常量等,也可以被存放与Dictionary和Array里
因为protocol是一种类型,所以可以用 is 操作符来确认是否被实现,也可以用as!,as?来类型转换
官方文档对protocol类型的表述:
Protocols do not actually implement any functionality themselves. Nonetheless, any protocol you create will become a fully-fledged type for use in your code.
Because it is a type, you can use a protocol in many places where other types are allowed, including:
- As a parameter type or return type in a function, method, or initializer
- As the type of a constant, variable, or property
- As the type of items in an array, dictionary, or other container
- 一个例子,2个数据Model类(存放原始数据),一个CustomCell类(用于table的数据展示,假设需要展示名字和年龄)。例子中protocol作为一个类型,充当了一个适配器
定义protocal:1
2
3protocol ModelForCustomCell {
func dataForCustomCell()->(name:String,age:String)
}
2个数据Model:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class ModelA : ModelForCustomCell{
var name: String!
var age: String!
func dataForCustomCell() -> (name:String,age:String) {
//实际应用中这里应该是写数据处理逻辑,组装成元组返回给调用的VC,避免在VC中写复杂的逻辑
self.name = "modelA"
self.age = "25"
return (self.name,self.age)
}
}
class ModelB : ModelForCustomCell{
var name: String!
var age: String!
func dataForCustomCell() -> (name:String,age:String) {
//实际应用中这里应该是写数据处理逻辑,组装成元组返回给调用的VC,避免在VC中写复杂的逻辑
self.name = "modelB"
self.age = "35"
return (self.name,self.age)
}
}
Note:
protocol中的方法返回的是元组
。在MVVM
模式下,Model类可以在extension
中写一个方法写数据处理逻辑,返回一个View需要的数据元组。这里数据元组起到了ViewModel
的作用
然后是我们的自定义tablelCell,要显示name,age两个数据1
2
3
4
5
6
7
8
9
10class CustomCell:UITableViewCell{
var nameLabel = UILabel()
var ageLabel = UILabel()
func configureCell(dataModel:ModelForCustomCell){
self.nameLabel.text = dataModel.dataForCustomCell().name
self.ageLabel.text = dataModel.dataForCustomCell().age
}
}
有2个table,分别显示ModelA和ModelB的名字和年龄,都可以用到CustomCell,在各自的table的dataSourece回调中可以这样写:
1 | func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ |
这样就可以对同一个cell适配显示不同的数据Model了