Swift闭包

闭包是功能性自包含模块,可以在代码中被传递和使用。Swift中的闭包和oc和c中的blocks块一样
闭包可以捕获和存储其所在上下文中任意常量和变量的引用。这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。Swift会为你管理在捕获过程中涉及的内存操作
闭包采用下列三种形式之一:
1、全局函数是一个有名字但是不会捕获任何值得闭包
2、嵌套函数是一个有名字并且可以捕获其封闭函数内的值的闭包
3、闭包表达式是一个利用轻量级语法写的可以捕获其上下文中的变量或者常量的没有名字的闭包。
Swift的闭包表达式有简介的风格,并鼓励在场景实现中实现语法优化,主要的优化如下:
1、利用上下文推断参数和返回值类型
2、单表达式闭包可以省略reurn关键字
3、参数名称简介
4、Trailing闭包语法
闭包表达式是一种利用简介语法构建内联闭包的方式
Swift类库中提供的sort函数,会根据提供的排序闭包将已知类型数组中的值进行排序
,排完序函数会返回一个与原数组一样大小的数组
1、 let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
2、闭包表达式语法
{ (parameters) -> returnType in
statements
}
闭包表达式语法可以使用常量、变量和 inout 类型作为参数,但不?供默认值。 也可以在 参数列表的最后使用可变参数。元组也可以作为参数和返回值。
reversed = sort(names, { (s1: String, s2: String) -> Bool in
 return s1 > s2
 })
闭包的函数体部分由关键字 in 引入。 该关键字表示闭包的参数和返回值类型定义已经完
成,闭包函数体即将开始。
 3、reversed = sort(names, { s1, s2 in return s1 > s2 } )//闭包的参数类型和返回类型可以被推断出来,所以可以省略
实际上任何情况下, 通过内联闭包表达式构造的闭包作为参数传递给函数时, 都可以推断出
闭包的参数和返回值类型,这意味着您几乎不需要利用完整格式构造任何内联闭包。

单行闭包return可以省略
4、reversed = sort(names, { s1, s2 in s1 > s2 } )
参数名简写
Swift 自动为内联函数?供了参数名称简写功能,您可以直接通过 $0,$1,$2 等名字来引用 的闭包的参数的值。
如果您在闭包表达式中使用参数名称简写, 您可以在闭包参数列表中省略对其的定义, 并且 对应参数名称简写的类型会通过函数类型进行推断。 in 关键字也同样可以被省略,因为此 时闭包表达式完全由闭包函数体构成:
5、reversed = sort(names, { $0 > $1 } )

Swift 的 String 类型定义 了关于大于号 (>) 的字符串实现,让其作为一个函数接受两个 String 类型的参数并返回 Bool 类型的值。 而这正好与 sort 函数的第二个参数需要的函数类型相符合。 以简单地传递一个大于号,Swift 可以自动推断出您想使用大于号的字符串函数实现:
6、 reversed = sort(names, >)
Trailing闭包
如果需要将一个很长的闭包表达式作为最后一个参数传递给函数, 可以使用 trailing 闭包 来增强函数的可读性。
Trailing 闭包是一个书写在函数括号之外(之后)的闭包表达式,函数支持将其作为最后一个 参数调用。
func someFunctionThatTakesAClosure(closure: () -> ()) {
}
//普通形势
someFunctionThatTakesAClosure({
})
//使用Trailing闭包
 someFunctionThatTakesAClosure() {
}
注意: 如果函数只需要闭包表达式一个参数, 当您使用 trailing 闭包时, 您甚至可以把 () 省略掉。
字典 digitNames 下标后跟着一个叹号 (!),因为字典下标返回一个可选值 (optional
value),表明即使该 key 不存在也不会查找失败。
let strings = numbers.map {}
map 在数组中为每一个元素调用了闭包表达式
捕获(Caputure)
闭包可以在其定义的上下文中捕获常量或变量。 即使定义这些常量和变量的原作用域已经 不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
Swift 最简单的闭包形式是嵌套函数, 也就是定义在其他函数体内的函数。 嵌套函数可以捕 获其外部函数所有的参数以及定义的常量和变量。
捕获的变量值不会修改,捕获并存储的是改变量的副本。
捕获的变量值会改变,捕获的是改变量的引用,,保证了当前函数结束不会消失,也保证了下一次执行的时候可以继续
Swift 会决定捕获引用还是拷贝值。 您不需要标注,swift会自动处理,当捕获的变量或者常量不再被使用到时,则会被清除
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
let incrementByTen = makeIncrementor(forIncrement: 10)
incrementByTen()
// 返回的值为 10
incrementByTen()
 // 返回的值为 20
let incrementBySeven = makeIncrementor(forIncrement: 7)
incrementBySeven()
// 返回的值为 7
incrementByTen()
// 返回的值为 40
如果您闭包分配给一个类实例的属性,并且该闭包通过指向该实例或其成员来捕获了
该实例, 您将创建一个在闭包和实例间的强引用环

打破这种强引用循环
引用计数至适用于类实例
解决循环引用是通过定义两个类之间的关系是弱或者无主引用而不是强引用
class   Person  {
let nameString
init(nameString) { self.name = name }
var apartmentApartment?
deinit { print("\(name) is being deinitialized") }
}

class   Apartment  {
let unitString
init(unitString) { self.unit = unit }
weak(或者使用unowned修饰) var tenantPerson?
deinit { print("Apartment \(unit) is being deinitialized") }
}

闭包是引用类型

闭包 仍然可以增加其捕获的变量值。 这是因为函数和闭包都是引用类型。
无论您将函数/闭包赋值给一个常量和变量,实际上就是将对应的常量或者变量设置为对应函数或者闭包的引用。这也意味着如果你将一个函数或者闭包赋值给两个变量或者常量那么,这两个常量或者变量指向的使用一个闭包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值