swift3-12 闭包

闭包 闭包(Closures)是自包含的功能代码块,可以在代码中使用或者用来传参传值。 Swift 的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的匿名函数比较相似。 全局函数和嵌套函数其实就是特殊的闭包。

闭包的形式有

全局函数: 有名字但不能捕获任何值
嵌套函数: 有名字,可以捕获封闭函数内的值
闭包表达式: 无名闭包,使用轻量级语法,可以根据上下文环境捕获值。

示例:

let clousuer = { print("Swift 闭包实例。") }
clousuer()


//加法
let sum = {(val1:Int, val2:Int)-> Int in
        return val1 + val2
}
let result = sum(20,2)

//排序
var arr:[Int] = []
for _ in 0...100{
    arr.append(Int(arc4random()%1000))
}
arr.sorted(by: {(a: Int, b:Int) -> Bool in

    return a > b
})

闭包的简化

//简化: 根据现场情况,选择适合当前情况的写法。
arr.sort(by:{a, b in return a > b}) //因为只能是 Int 类型的,可以省去声明
arr
arr.sort(by:{a, b in  a < b})  //省去 Return
arr
arr.sort(by: {$0>$1}) //$0, $1(从0开始,表示第i个参数...) 省去参数,直接使用简化参数名
arr

运算符函数

arr.sort(by: <) //可以这样写的原因是 Swift中,> < = + - 等,本身就是函数
arr

尾随闭包 Trailing closure syntax 尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用

//把闭包写在()外边
arr.sorted(){a, b in
    return a > b
}
//由于么有参数需要传入,()也可以省略
arr.sorted{a, b in
    return a > b
}
arr.sorted{$0 > $1}


//实现一个小动画
import UIKit
import XCPlayground

let showView = UIView(frame:CGRect(x:0,  y:0, width:300, height:300))
let rectAngle = UIView(frame:CGRect(x:0,  y:0, width:50, height:50))
rectAngle.center = showView.center
showView.backgroundColor = UIColor .white
rectAngle.backgroundColor = UIColor.red
showView.addSubview(rectAngle)
XCPlaygroundPage.currentPage.liveView = showView
UIView.animate(withDuration: 4.0, animations: {
    rectAngle.backgroundColor = UIColor.orange
    rectAngle.frame = CGRect(x:0,  y:0, width:300, height:300)
})

内容捕获 闭包可以在其定义的上下文中捕获常量或变量

var arr:[Int] = []
for _ in 0...100{
    arr.append(Int(arc4random()%1000))
}

var num = 300
arr.sorted{
    a, b in abs(a - num) < abs(b - num)
}

闭包是引用类型 无论您将函数/闭包赋值给一个常量还是变量,实际上都是将常量/变量的值设置为对应函数/闭包的引用

func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementor() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementor
}

let incrementByTen = makeIncrementor(forIncrement: 10)

// 返回的值为10
incrementByTen()

// 返回的值为20
incrementByTen()

// 返回的值为30
incrementByTen()

// 返回的值为40
incrementByTen()

let alsoIncrementByTen = incrementByTen

// 返回的值为50
print(alsoIncrementByTen())