1.什么时候会发生循环引用
原理跟OC中的block类似, 当有个属性记录下了函数传递回来的闭包, 产生强引用, 就会发生闭包的循环引用
2.怎么解决循环引用
如何解决闭包的循环引用, 同样有三种方式:
-
使用weak修饰变量, 打破强引用, 因为使用weak修饰的变量有一次变成nil的机会
-
使用[weak self] 修饰闭包原理跟__weak类似, 这样在闭包中使用self, 就是弱引用
-
使用[unowned self ] 修饰闭包, 跟__unsafe_unretained类似, 不安全
3.如何判断是否发生强引用, 闭包中使用析构函数
- 代码:
//swift dealloc
//析构函数
deinit{
print("销毁")
}
- storyboard:
4.Swift中的代码
import UIKit
class ViewController: UIViewController {
var finishedCallBack: ( (dataString: String) -> () )?
override func viewDidLoad() {
super.viewDidLoad()
//解决方式三: [unowned self] 跟 _unsafe_unretained 类似 不推荐使用
loadData { [unowned self] (dataString) -> () in
print("\(dataString) \(self.view)")
}
}
func method2() {
//解决方式二: 在swift中 有特殊的写法 ,跟OC __weak 相似 [weak self]
loadData { [weak self] (dataString) -> () in
//以后在闭包中中 使用self 都是若引用的
print("\(dataString) \(self?.view)")
}
}
func method1() {
// 解决方式一: weak
weak var weakSelf = self
loadData { (dataString) -> () in
print("\(dataString) \(weakSelf?.view)")
}
}
func loadData(finished: (dataString: String) -> ()) {
// 记录闭包
self.finishedCallBack = finished
//加载数据
dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
print("执行耗时操作")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//执行回调
self.working()
})
}
}
func working() {
self.finishedCallBack?(dataString: "<html>")
}
//swift dealloc
//析构函数
deinit {
print("销毁")
}
}
网友评论
let arr = ["yi lian mengbi",myString]
myString = "SUPER"
print(arr,"\n",myString)
输出的数组的值和oc里面是不同的
相反的,当捕获引用有时可能会是nil时,将闭包内的捕获定义为弱引用。弱引用总是可选类型,并且当引用的实例被销毁后,弱引用的值会自动置为nil。这使我们可以在闭包内检查它们是否存在。
我在另外一个地方看到的是推荐使用unowned self