10.Swift 中的闭包

前端之家收集整理的这篇文章主要介绍了10.Swift 中的闭包前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在Objective-C中,我们有block,在Swift中,我们有闭包,两者之间基本上一致,没有多大的区别,非要说起不同,也就是声明的语法有些差异,还有一些特性上的差异,下面让我们来看看.


1.前言

在讲闭包之前,我们来看看一个简单的例子:

let array = [1,2,3,5,10,20,30]

func backwards(s1: Int,s2: Int) -> Bool {
    return s1 > s2
}

var reversed = array.sort(backwards)

print(reversed)

// 打印出来的结果:
// [30,20,10,5,3,2,1]

这是一个排序的例子,再想想,貌似没有了更好的简洁方式了吧,但这一切也只是在没有闭包之前,下面让我们来看看闭包的强大之处.


2.闭包表达式语法

reversed = array.sort( { (s1: Int,s2: Int) -> Bool in return s1 > s2 } )

这个就是闭包表达式的语法,完全不需要另外新建一个函数,就可以完成排序的操作.


3.根据上下文推断类型

reversed = array.sort({s1,s2 in return s1 > s2})

这也是一种闭包的写法,Swift中有一个特性就是会根据上下文去推断类型,而闭包也是可以如此的,所以我们可以直接这么写.


4.单表达式闭包隐式返回

reversed = array.sort({ s1,s2 in s1 > s2})

在闭包里,单行的闭包是可以不需要写return关键字的,默认就会返回.


5.参数名称缩写

reversed = array.sort( { $0 > $1 } )

这种写法也是闭包的表达式,不需要写参数名,就可以直接排序.


6.运算符函数

reversed = array.sort(>)

这种写法也是闭包的表达式,完全不需要任何参数,直接写明一个运算符就可以完成排序,但这种写法不太好,只能完成一些比较简单的排序.


7.尾随闭包

所谓的尾随闭包,就是自己声明一个闭包函数,在别的地方去调用.

func someFunctionThatTakesAClosure(closure: () -> Void) { // 闭包函数体 } // 写法一 someFunctionThatTakesAClosure({ // 闭包函数体 }) // 写法二 someFunctionThatTakesAClosure() { // 闭包函数体 }

8.map函数

在Swfit原生当中,有一个叫做map(_:)的函数,它也是一个闭包类型,下面让我们来看看.

let people = ["ZhangSan","LiSi","WangWu"]

let person = people.map { (var name) -> String in

    print(name)

    return name
}

map的用法和For-in有些类似,它会映射数组的元素,然后遍历,直到遍历到最后一个元素为止.


9.自动闭包和闭包的延迟操作

var numberArray = [1,4,6,7,8,9]

print(numberArray.count)
// 输出的结果为: 9

let customerProvider = { numberArray.removeAtIndex(0) }

print(numberArray.count)
// 输出的结果为: 9

print("Now serving \(customerProvider())!")
// 输出的结果为: Now serving 1!

print(numberArray.count)
// 输出的结果为: 8

这里的customerProvider就相当于我们自定义的一个闭包函数,虽然在闭包里,已经移除了一个元素,但该闭包并没有被调用,所以元素不会被移除.


10.闭包的其他知识

这里还有一个叫做逃逸闭包,和非逃逸闭包的概念:

所谓的逃逸闭包就是当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸,也就是说,在函数外部可访问,而非逃逸闭包就是只能在函数内部访问,一旦函数运行结束,闭包也就结束了.

这里有几个关键字: @noescape,@autoclosure,@autoclosure(escaping)

@noescape关键字来标注的闭包,就会变成非逃逸闭包,说明该闭包不能被函数外部所访问.

@autoclosure关键字来标注的参数,则会自动把参数转变成自动闭包,注意@autoclosure关键也是含有@noescape关键的特性,所以用@autoclosure来标注的闭包参数是不可以逃逸的.

@autoclosure(escaping)关键字来标注的参数,并且可逃逸.

var numberArray = [1,9]

func someFunctionWithNoescapeClosure(@noescape closure: () -> Void) { closure() } func serveCunstomer(@autoclosure customerProvider: () -> Int) { print("Now serving \(customerProvider())!") } var customerProviders: [() -> Int] = []

func collectCustomerProviders(@autoclosure(escaping) customerProvider: () -> Int) { customerProviders.append(customerProvider) }

这里有个例子,有兴趣的朋友可以自己去研究看看,如果想看更加详细的内容,可以去参考官方文档.


这次就讲到这里,下次继续

猜你在找的Swift相关文章