Swift:闭包Closures简析

相对于OC的block有很多差异

Nonescaping 逃逸闭包

Swift闭包Closure的概念类似于OC中的Block,但使用上有很多差异,首先,Swift3.x中,传递闭包到函数中的时候,系统会默认为非逃逸闭包类型 (Nonescaping Closures),有非逃逸闭包类型必然就有逃逸闭包(Escaping Closures),两种类型主要差别在于生命周期。

lifeCycle 生命周期

非逃逸闭包指把闭包作为参数传递给函数–>函数中运行该闭包–>退出函数–>release

逃逸闭包其生命周期可能长于相关函数,当函数退出的时候,逃逸闭包的引用仍然被其他对象持有,不会在相关函数结束后释放,可用于异步回调等场景。

从中我们可以看到Swift在对内存管理上与OC的差异,更严格的内存管理也是Swift比OC高效的原因。

写法

逃逸闭包需要用@escaping标记:

1
func doSomething(callback: @escaping (_ responseObject: String)->()){}

简写

了解一下Closures的便捷写法,举个例子:

1
2
let list = [“a", “b", "c", "d”]
let sortedList = list.sort { (one: String, two: String) -> Bool inreturnone < two }

可以这么简化:

1
let sortedList = list.sort { (one, two) -> Bool in return one < two }

返回类型也可以推算出来,所以可以去掉闭包的返回类型:

1
let sortedList = list.sort { (one, two) in return one < two }

可以用$i符号替换掉参数的名字,代码然后就变成这样:

1
let sortedList = list.sort { return $0 < $1 }

在单语句的闭包中,关键字return也可以省略。最后一条语句的返回值就变成闭包的返回值:

1
let sortedList = list.sort { $0 < $1 }

到目前已经变得非常简单了,但还可以继续优化。

对字符串来说,有一个字符串比较函数,定义如下:

1
func <(lhs: String, rhs: String) -> Bool

使用这个函数可以让你的Code更加简洁, 如下:

1
let sortedList = list.sort(<)

总结

Swift学习了一段时间后,通过了解其对内存的管理明显感觉到一种与OC不同的编程思想,这才是Swift的魅力所在。

参考

docs.swift.org

  Total:    No.