swift 【block】

  • block闭包表达式

在 swift中可以用 func 定义一个函数,也可以用闭包表达式定义一个函数

func sum(v1:Int, v2:Int) -> Int { v1 + v2 }
let sum2 = { (v1:Int, v2:Int) -> Int in
    return v1 + v2
}
sum(v1: 10, v2: 20)//func定义的函数
sum2(10, 20)//闭包表达式定义的函数
 func sun(param1:Int, param2:Int, test:( Int, Int) -> Int) {
    print(test(param1, param2))
 }

 sun(param1:20 , param2:20, test:{
    (v1:Int, v2:Int) -> Int in
    return v1 + v2
 })
//闭包表达式简写
 sun(param1:20 , param2:20, test:{
    v1, v2 -> Int in
    return v1 + v2
 })
 sun(param1:20 , param2:20, test:{
    v1, v2  in
    return v1 + v2
 })
//闭包表达式隐式返回
 sun(param1:20 , param2:20, test:{
    v1, v2  in  v1 + v2
 })
//参数名称简写
sun(param1:20 , param2:20, test:{
   $0 + $1
})
//函数式闭包
sun(param1: 2, param2: 3, test: +)

  • 尾随闭包

最后一个参数是闭包表达式的时候,可以独立于前面的参数,写在函数参数外面的闭包表达式,使结构看起来再加清晰整洁,属于结构优化,默认闭包表达式作为参数的时候采用尾随闭包的形式。

sun(param1: 12, param2: 13) { (v1:Int, v2:Int) -> Int in
    return v1 + v2
 }
//尾随闭包表达式
sun(param1: 12, param2: 13) { v1, v2 in
     v1 + v2
 }
//尾随闭包表达式简写
sun(param1: 20, param2: 12) { return $0 + $1 }
//尾随闭包表达式简写
sun(param1: 10, param2: 12) { $0 + $1 }
sun(param1: 10, param2: 12) { $0 + $1 }

sun(param1: 2, param2: 3, test: +)

  • 自动闭包

顾名思义根据传入的参数,自动生成闭包;延迟执行,属于性能优化,除些之外也属于结构优化,调用者无需关心参数类型,用@autoclosure 修饰。

@autoclosure 只支持()->T 的格式参数,并且不仅仅只支持最后一个参数。

系统的合并运算符??属于自动闭包。

自动闭包允许你延迟处理,因此闭包内部的代码直到你调用它的时候才会运行。

//添加 @autoclosure 关键字, 当闭包被调用的时候,会返回被包装在其中的表达式的值
public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = String(), file: StaticString = #file, line: UInt = #line) {
    if !condition() {
        print(message())
    }
}
let number = 3
assert(number > 3, "number 不大于3")  //输出: number 不大于3
//自动闭包允许延迟处理
var person = ["zhangsan", "lisi", "wangwu", "zhailiu"]
print(person.count)    // 输出: 4
let deletePerson = { person.remove(at: 0) }
print(person.count)   //此时输出还是 4,因为没有调用闭包没有被调用,闭包里的代码没有被执行

//此时调用闭包
print(deletePerson())  //输出 "zhangsan"
print(person.count)    //输出: 3
//闭包作为实际参数传递给函数时,能获得同样的延时求值行为
//闭包作为实参, 可以显示的使用闭包
var person = ["zhangsan", "lisi", "wangwu", "zhailiu"]
func serve(customer customerProvider: () -> String) {
    print("Now serving \(customerProvider())!")
}
//函数接受一个返回顾客名字的显式的闭包
serve(customer: { person.remove(at: 0) })  //打印: Now serving zhangsan!
//自动闭包作为实际参数
var person = ["zhangsan", "lisi", "wangwu", "zhailiu"]
//customerProvider 参数将自动转化为一个闭包,因为该参数被标记了 @autoclosure 特性
func serve(customer customerProvider: @autoclosure () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: person.remove(at: 0))  //打印: Now serving zhangsan!

  • 自动+逃逸

//自动闭包允许逃逸,同时使用 @autoclosure 和 @escaping 标志
var customerInLine = ["zhangsan", "lisi", "wangwu", "zhaoliu"]
var customerProviders: [() -> String] = []
func collectionCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
    customerProviders.append(customerProvider)
}
print(customerProviders.count)   //打印: 0
collectionCustomerProviders(customerInLine.remove(at: 0))
collectionCustomerProviders(customerInLine.remove(at: 0))
print(customerInLine.count)   //打印: 4
print(customerProviders.count)  //打印: 2

for c in customerProviders {
    print("Now serving \(c())")
}
/*
 Now serving zhangsan
 Now serving lisi
 */

collectCustomerProviders(_ : ) 函数并没有调用传入的 customerProvider 闭包,而是将闭包追加到了 customerProviders 数组中。
这个数组定义在函数作用域范围外,这意味着数组内的闭包能够在函数返回之后被调用。
因此,customerProvider 参数必须允许“逃逸”出函数作用域。

  • swift 闭包值捕获

  • 闭包可以对外部函数的变量、常量进行捕获;
  • 闭包捕获时机是在函数执行完,return 时再去捕获
  • 当函数里有多个闭包时,只会对变量、常量捕获一次,多个闭包对捕获的变量、常量共享
  • 闭包不会对全局变量进行捕获

闭包可以在其被定义的上下文中捕获常量或者变量。即是定义这些常量和变量的原作用域已经不存在了,闭包仍然可以在闭包函数体内引用和修改这些值。

  • 闭包类型

和类一样,闭包也是引用类型

  • 闭包

闭包和闭包表达式并不一是一个东西,半包表达式是函数的另外一种定义,而闭包是一个函数和它所捕获变量/常量环境的组合;

一般指定义在函数内部的函数;一般它捕获的是外层函数的局部变量/常量;

闭包和和闭包表达式的区别?

闭包表达式是:函数的另外一种表现形式,为了实现简介和高效,有不同的表现形式,例如自动闭包,尾随闭包;
闭包是:封装在函数中的函数或者闭包表达式,且捕获了局部变量的运行环境。它运用了闭包表达式,但闭包表达式不是闭包。

  •  循环引用的问题

    objective-c解决闭包的循环引用问题一般是先声明__weak typedef(weakSelf) = self;然后使用weakSelf对本类的属性调用。
    swift中也有类似于objective-c中的方法:首先是声明:weak var weakSelf = self;然后使用weakSelf对本类的属性调用。self可能会为nil,所以需要用var。

  • 闭包内修改外部变量

在objective-c中,我们通常使用__block来声明一个变量,这样就可以在闭包内对这个变量进行修改。
在swift中没有__block这种关键字,但是swift中的闭包是做了优化处理,是可以直接捕获上下文中的变量。所以可以直接在闭包中对变量进行修改。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值