swift逃逸闭包和自动闭包

当闭包作为一个实际参数传递给一个函数的时候,并且它会在函数返回之后调用我们就说这个闭包逃逸了,当你声明一个接受闭包作为形式参数的函数时,你可以在形式参数前写@escaping来明确闭包是允许逃逸的。

闭包可以逃逸的一种方法是被存储在定义与函数外的变量里,比如说,很多函数接受闭包实际参数来作为启动异步任务的回调。函数在启动任务后返回,但是闭包要直到任务完成--闭包需要逃逸,以便于稍后调用

//: A UIKit based Playground for presenting user interface

import UIKit
var completionHansdlsers:[()-> Void] = []
func someFuntionWIthEscapingClosure(completionHandler:@escaping ()->Void){
    completionHansdlsers.append(completionHandler)
}

让闭包@escaping 意味着你必须在闭包中显示地引用self

//: A UIKit based Playground for presenting user interface

import UIKit
var completionHansdlsers:[()-> Void] = []
func someFuntionWIthEscapingClosure(completionHandler:@escaping ()->Void){
    completionHansdlsers.append(completionHandler)
}

func someFuntionWithNoneScapingClosure(closure:()->Void){
    closure()
}

class SomeClass{
    var x = 10
    func doSomething(){
        someFuntionWIthEscapingClosure {
            self.x=100
        }
        
        someFuntionWithNoneScapingClosure {
            x=200
        }
    }
}

let instance = SomeClass()
instance.doSomething()
print(instance.x)
//200
completionHansdlsers.first?()
print(instance.x)
//100

自动闭包

自动闭包是一种自动创建的用来把作为实际参数传递给函数的表达式打包的闭包。它不接受任何实际参数,并且当它被调用时,它会返回内部打包的表达式的值

这个语法的好处在于通过写普通表达式代替显示闭包而使你省略保卫函数形式参数的括号

下面代码不能执行。。。是系统的源码

autoclosure 就是自动闭包

//: A UIKit based Playground for presenting user interface

import UIKit
public func assret(_ condition:@autoclosure() -> Bool,_ message:@autoclosure() -> String = String(),file:StaticString=#file ,line:UInt = #line
let number = 3
assert(number > 3,"number不大于3")

自动闭包允许你延迟处理,因此闭包内部的代码直到你调用它的时候才会运行,对于有副作用或者占用资源的代码来说很有作用。

因为它可以允许你控制代码何时才进行求值

//: A UIKit based Playground for presenting user interface

import UIKit
var customersInLine = ["Chris","Alex","Ewa","Barry","Daniella"]
//54  06:03
print(customersInLine.count)
//相当于没有执行
let customProvider = {customersInLine.remove(at: 0)}
print(customersInLine.count)
//调用闭包表达式的时候才真正执行
print("Now serving \(customProvider())!")

print(customersInLine.count)

当你传一个闭包作为实际参数到函数的时候,你会得到与延迟处理相同的行为。

//: A UIKit based Playground for presenting user interface

import UIKit
var customersInLine = ["Chris","Alex","Ewa","Barry","Daniella"]

//相当于没有执行
let customProvider = {customersInLine.remove(at: 0)}

func serve(custom customerProvider:() ->String){
    print("Now serving\(customerProvider())!")
}
serve(custom: {customersInLine.remove(at: 0)})

自动闭包

通过@autoclosure标志标记它的形式参数使用了自动闭包,现在你可以调用函数就像它接受了一个Sting 实际参数而不是闭包。实际参数自动地转换为闭包,因为customerProvider形式参数的类型被标记为 @autocloseure 标记

//: A UIKit based Playground for presenting user interface

import UIKit
var customersInLine = ["Chris","Alex","Ewa","Barry","Daniella"]

//相当于没有执行
let customProvider = {customersInLine.remove(at: 0)}

func serve(custom customerProvider:@autoclosure() ->String){
    print("Now serving \(customerProvider())!")
}
serve(custom: customersInLine.remove(at: 0))

自动+逃逸

如果你想要自动闭包允许逃逸,就同时使用@autoclosure 和@escaping标志

//: A UIKit based Playground for presenting user interface

import UIKit
var customersInLine = ["Chris","Alex","Ewa","Barry","Daniella"]
var customerProviders:[()->String]=[]

func collectCustomerProviders(_ customerProvider:@autoclosure @escaping()->String){
    customerProviders.append(customerProvider)
}
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))

print("Collecte d\(customerProviders.count) closures")
//prings "Collected 2 closures"

for customerProvider in customerProviders{
    print("Now serving \(customerProvider())!")
}
Collecte d2 closures
Now serving Chris!
Now serving Alex!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安果移不动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值