在Objective-C中,我们有block,在Swift中,我们有闭包,两者之间基本上一致,没有多大的区别,非要说起不同,也就是声明的语法有些差异,还有一些特性上的差异,下面让我们来看看.
1.前言在讲闭包之前,我们来看看一个简单的例子:
let @H_301_8@array = [1,2,3,5,10,20,30]func backwards(s1: Int,s2: Int) -> Bool { @H_301_8@return s1 > s2}@H_301_8@var reversed = @H_301_8@array.sort(backwards)@H_301_8@print(reversed)// 打印出来的结果:// [30,20,10,5,3,2,1]
这是一个排序的例子,再想想,貌似没有了更好的简洁方式了吧,但这一切也只是在没有闭包之前,下面让我们来看看闭包的强大之处.
2.闭包表达式语法reversed = array.sort( { (s1: Int,s2: Int) -> Bool @H_301_8@in @H_301_8@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.@H_301_8@sort( { > reversed } )
这种写法也是闭包的表达式,不需要写参数名,就可以直接排序.
6.运算符函数array.sort(>)=(closure: () -> VoID)
这种写法也是闭包的表达式,完全不需要任何参数,直接写明一个运算符就可以完成排序,但这种写法不太好,只能完成一些比较简单的排序.
7.尾随闭包所谓的尾随闭包,就是自己声明一个闭包函数,在别的地方去调用.
func someFunctionThatTakesAClosuresomeFunctionThatTakesAClosure { // 闭包函数体 } // 写法一 //({ someFunctionThatTakesAClosure 闭包函数体 }) // 写法二 ()let { // 闭包函数体 }
8.map函数 在Swfit原生当中,有一个叫做map(_:)的函数,它也是一个闭包类型,下面让我们来看看.
"ZhangSan" people = ["liSi","WangWu",let]var person = people.map { (print name) -> String @H_301_8@in 1(name) @H_301_8@return name}
map的用法和For-in有些类似,它会映射数组的元素,然后遍历,直到遍历到最后一个元素为止.
9.自动闭包和闭包的延迟 *** 作@H_301_8@var numberArray = [4,6,7,8,9,// 输出的结果为: 9]@H_301_8@print(numberArray.count)0let customerProvIDer = { numberArray.removeAtIndex(// 输出的结果为: 9) }@H_301_8@print(numberArray.count)"Now serving \(customerProvIDer())!"@H_301_8@print(// 输出的结果为: Now serving 1!)// 输出的结果为: 8@H_301_8@print(numberArray.count)var
这里的customerProvIDer就相当于我们自定义的一个闭包函数,虽然在闭包里,已经移除了一个元素,但该闭包并没有被调用,所以元素不会被移除.
10.闭包的其他知识这里还有一个叫做逃逸闭包,和非逃逸闭包的概念:
所谓的逃逸闭包就是当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸,也就是说,在函数外部可访问,而非逃逸闭包就是只能在函数内部访问,一旦函数运行结束,闭包也就结束了.
这里有几个关键字: @noescape,@autoclosure,@autoclosure(escaPing)
@noescape关键字来标注的闭包,就会变成非逃逸闭包,说明该闭包不能被函数外部所访问.
@autoclosure关键字来标注的参数,则会自动把参数转变成自动闭包,注意@autoclosure关键也是含有@noescape关键的特性,所以用@autoclosure来标注的闭包参数是不可以逃逸的.
@autoclosure(escaPing)关键字来标注的参数,并且可逃逸.
1 numberArray = [9,@noescape]func someFunctionWithNoescapeClosure(closure closure: () -> VoID) { ()func } serveCunstomer @autoclosure(print customerProvIDer: () -> Int) { "Now serving \(customerProvIDer())!"(var) } customerProvIDers (): [@autoclosure -> Int] = []func collectCustomerProvIDers(customerProvIDers(escaPing) customerProvIDer: () -> Int) { append.(customerProvIDer) }
这里有个例子,有兴趣的朋友可以自己去研究看看,如果想看更加详细的内容,可以去参考官方文档.
这次就讲到这里,下次继续
总结以上是内存溢出为你收集整理的10.Swift 中的闭包全部内容,希望文章能够帮你解决10.Swift 中的闭包所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)