* 闭包是自包含的函数代码块,可以在代码中被传递和使用。Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的匿名函数比较相似
* 闭包可以捕获和存储其所在上下文中任意常量和变量的引用。这就是所谓的闭合并包裹着这些常量和变量,俗称闭包
* 闭包的使用和block一样, 用于保存一段代码, 用作回调, 用作执行耗时操作
* 闭包格式: in关键字的目的是便于区分返回值和执行语句
'' {
'' (参数) -> 返回值类型
'' in
'' 执行语句
'' }
'' func loadData3(name: String, finished: () -> ()){
'' print("name = \(name)")
'' finished()
'' }
func loadData2(finished: () -> ()){
'' print("耗时操作")
'' // 回调
'' finished()
'' }
func loadData(){
'' dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
'' print(NSThread.currentThread())
'' print("耗时操作")
'' dispatch_async(dispatch_get_main_queue(), { () -> Void in
'' print(NSThread.currentThread())
'' print("回到主线程更新UI")
'' })
'' }
'' }
闭包简写:
'' 1.如果没有参数, 没有返回值, in和in之前的东西可以省略
'' 2.如果闭包是函数的最后一个参数, 可以写在()后面 -- 尾随闭包
'' 3.如果只有一个闭包参数, 那么()也可以省略 -- 尾随闭包
'' loadData2{
'' print("执行回调")
'' }
'' loadData3("lnj") { () -> () in
'' print("执行回调")
'' }
*循环引用问题*
* 弱引用
> OC
* \_\_weak typeof(self) weakSelf = self
* \_\_unsafe\_unretained typeof(self) weakSelf = self;
> Swift
* Swift中同样提供了两种办法用来解决你在使用类的属性时所遇到的循环强引用问题:弱引用(weak reference)和无主引用(unowned reference)
* weak var weakSelf = self
* unowned var weakSelf = self
应用场景:
* 对于生命周期中会变为nil的实例使用弱引用
* 对于初始化赋值后再也不会被赋值为nil的实例,使用无主引用
捕获列表
* Swift 提供了一种优雅的方法来解决闭包导致的循环强引用,称之为闭包捕获列表(closuer capture list)
'' 调用时在闭包的参数列表前通过[]说明捕获列表
'' 例如: loadData { [weak self] () -> () in}
> 注意
* 和OC一样, 如果你试图在实例被销毁后,访问该实例的无主引用,会触发运行时错误
*闭包循环强引用*
* block
* 闭包和block很像, 都是提前准备好代码, 在需要时执行
* block会对外部变量进行强引用, 保证执行代码时变量还在
* block中用到self一定要非常小心
* 闭包
* 闭包也一样, 会对外部变量进行强引用, 保证执行代码时变量还在
* 如果您将闭包赋值给一个类实例的属性,并且该闭包通过访问该实例或其成员而捕获了该实例,您将创建一个在闭包和该实例间的循环强引用
* Swift开发中能不写self就不写self, 一看到self就想到闭包
*析构函数*
* 析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用
* 类似于OC中的dealloc方法
* 析构器是在实例释放发生前被自动调用。你不能主动调用析构器
* 一般情况下, 当使用自己的资源时, 在析构函数中进行一些额外的清理
* 例如,如果创建了一个自定义的类来打开一个文件,并写入一些数据,你可能需要在类实例被释放之前手动去关闭该文件