第一成品网站,做网站的文章,个人怎么免费注册公司流程,wordpress移机1 闭包的本质其实是一个引用类型#xff1a;存储在堆空间上#xff0c;由堆分配空间#xff0c;且生命周期由ARC#xff08;自动引用计数机制#xff09;管理
2 捕获值#xff1a;闭包会捕获上下文使用到的变量#xff08;引用类型会保持引用关系#xff09;#xff…1 闭包的本质其实是一个引用类型存储在堆空间上由堆分配空间且生命周期由ARC自动引用计数机制管理
2 捕获值闭包会捕获上下文使用到的变量引用类型会保持引用关系如果没有显式捕获列表 swift会默认按值捕获局部变量或对引用类型捕获强引用。为了避免强引用循环可以通过[weak self]或[unowned self]来避免。如下所示
class Counter {var total 0func makeIncrementer() - () - Int {return { [unowned self] inself.total 1return self.total}}
}let counter Counter()
let incrementer counter.makeIncrementer()
print(incrementer()) // 输出: 1
print(incrementer()) // 输出: 2
print(counter.total) // 输出: 2
3 延迟执行
闭包中的代码只有在闭包被调用时才会执行适合回调和异步任务。
let greeting: () - Void {print(Hello, Swift!)
}print(Before calling the closure)
greeting() // 闭包被调用这里的代码才会执行
print(After calling the closure)输出
Before calling the closure
Hello, Swift!
After calling the closure
闭包延迟执行在事件处理中的应用举例比如我要给网络发送一条请求得到数据来更新我的UI视图但是网络的响应时间我们是不确定的所以就会导致更新UI的时机并不确定。我们就可以借助逃逸闭包escaping来解决这个问题escaping 用于标记闭包参数表示这个闭包可能会在函数返回后被异步调用。闭包会在函数作用域之外执行而不是在函数调用时立即执行然后在闭包中执行更新逻辑。如下面的例子我们在闭包中更新answer就可以解决该问题了。
func chatRequest(inputId : String,input : String,completion:escaping(String) - Void) {//completion会异步自动调用completion(String)
}if let question questions{request?.chatRequest(inputId:inputID,input: question){[weak self] answer inself?.answer answer}
}