Swift笔记 - 代理和闭包

       最近在把公司原 OC 项目 Swift 化,学到了很多东西,做个笔记记录下。

一、代理(delegate)

1.代理的说明

       首先解释关于代理。代理(delegate)是 Cocoa 的一个术语,表示将一个对象的部分功能转交给另一个对象。

       比如对象 A 希望对象 B 知道将要发生或已经发生某件事情,对象A可以把对象B的引用存为一个实例变量。这个对象B称为委托。当事件发生时,它检查委托对象是否实现了与该事件相适应的方法。如果已经实现,则调用该方法。

       由于松耦合的原因,一个对象能成为多个对象的代理。某些情况下,相较于通过继承让子类实现相关的处理方法,可以有效减少代码复杂度。所以 iOS 中也大量的使用了代理。

2.代理的使用

2.1 自定义cell的类,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
protocol TestTableCellDelegate:NSObjectProtocol {
//这里我设置方法传入的是一个模型,大家可根据需要传入不同值,用法和 OC 一样,写法稍有不同。
func selectedGroup(model:LXGroupModel)
func deletedGroup(model:LXGroupModel)
func modifyGroup(model:LXGroupModel)
}

class TEstTableViewCell: UITableViewCell {
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}

@IBAction func groupClick(_ sender: UIButton) {
self.delegate.selectedGroup(model: self.model!)
}

@IBAction func modeifyClick(_ sender: UIButton) {
self.delegate.modifyGroup(model: self.model!)
}

@IBAction func deletedClick(_ sender: UIButton) {
self.delegate.deletedGroup(model: self.model!)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
}

2.2 Controller 类的核心代码

       这里和 OC 没有区别,主要声明 cell 的代理,创建 cell 时,把响应焦点设置为当前类。

1
2
3
class TestViewController: UIViewController, UITableViewDelegate, UITableViewDataSource,TestTableCellDelegate{

}
1
2
3
4
5
6
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:TestTableViewCell = (tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell", for: indexPath) as? LXSwiftGroupTableViewCell)!
cell.model = groupArray?[indexPath.row] as? LXGroupModel
cell.delegate = self
return cell
}

2.3 实现代理方法

1
2
3
4
5
6
7
8
9
10
11
func selectedGroup(model: LXGroupModel) {
...
}

func deletedGroup(model: LXGroupModel) {
...
}

func modifyGroup(model: LXGroupModel) {
...
}

二、OC 中的 Block,Swift 中的 Closure(闭包)

1.闭包的说明

       Swift 中的闭包和 Objective-C 中的 block 类似,闭包是功能性自包含模块,可以在代码中被传递和使用。 在 Swift 中 函数只是闭包的一种特殊形式。

1.全局函数是一个有名字但不会捕获任何值的闭包
2.内嵌函数是一个有名字可以捕获到所在的函数域内值的闭包
3.闭包表达式是一个没有名字的可以捕获上下文中的变量或者常量的闭包

2.闭包的使用

2.1 方式一:利用typealias最完整的创建

Swift
1
2
3
4
5
6
7
8
9
10
11
//为(_ num1: Int, _ num2: Int) -> (Int) 类型的闭包定义别名:Add
typealias Add = (_ num1: Int, _ num2: Int) -> (Int)
//创建一个 Add 类型的闭包常量:addCloser1
let addCloser1: Add
//为已经创建好的常量 addCloser1 赋值
addCloser1 = {
(_ num1: Int, _ num2: Int) -> (Int) in
return num1 + num2
}
//调用闭包并接受返回值
let result = addCloser1(20, 10)

2.2 方式二:闭包类型申明和变量的创建合并在一起

Swift
1
2
3
4
5
6
7
8
9
//创建一个 (_ num1: Int, _ num2: Int) -> (Int) 类型的闭包常量:addCloser1
let addCloser1: (_ num1: Int, _ num2: Int) -> (Int)
//为已经创建好的常量 addCloser1 赋值
addCloser1 = {
(_ num1: Int, _ num2: Int) -> (Int) in
return num1 + num2
}
//调用闭包并接受返回值
let result = addCloser1(20, 10)

2.3 方式三:省略闭包接收的形参、省略闭包体中返回值

Swift
1
2
3
4
5
6
7
8
9
//创建一个 (Int, Int) -> (Int) 类型的闭包常量:addCloser1
let addCloser1: (Int, Int) -> (Int)
//为已经创建好的常量 addCloser1 赋值
addCloser1 = {
(num1, num2) in
return num1 + num2
}
//调用闭包并接受返回值
let result = addCloser1(20, 10)

2.4 方式四:在形式三的基础上进一步精简

Swift
1
2
3
4
5
6
7
//创建一个 (Int, Int) -> (Int) 类型的闭包常量:addCloser1 并赋值
let addCloser1: (Int, Int) -> (Int) = {
(num1, num2) in
return num1 + num2
}
//调用闭包并接受返回值
let result = addCloser1(20, 10)

2.5 方式五:如果闭包没有接收参数省略in

Swift
1
2
3
4
5
6
//创建一个 () -> (String) 类型的闭包常量:addCloser1 并赋值
let addCloser1: () -> (String) = {
return "这个闭包没有参数,但是有返回值"
}
//调用闭包并接受返回值
let result = addCloser1()

2.6 方式六:简写的实际参数名

swift Swift //创建一个 (String, String) -> (String) 类型的闭包常量:addCloser1 并赋值 let addCloser1: (String, String) -> (String) = { return "闭包的返回值是:\($0),\($1)" } //调用闭包并接受返回值 let result = addCloser1("Hello", "Swift!")

说明: 得益于Swift的类型推断机制,我们在使用闭包的时候可以省略很多东西,而且Swift自动对行内闭包提供简写实际参数名,你也可以通过 $0, $1, $2 这样的语法来引用闭包的实际参数值。如果你在闭包表达式中使用这些简写实际参数名,那么你可以在闭包的实际参数列表中忽略对其的定义,并且简写实际参数名的数字和类型将会从期望的函数类型中推断出来。in关键字也能被省略,$0 和 $1 分别是闭包的第一个和第二个 String类型的 实际参数(引自文档翻译)。

以上。

------本文结束 感谢阅读------

本文地址:http://kaaaaai.cn/articles/024.html
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处,谢谢!

众筹项目:拯救世界!
0%