闭包循环引用
block
- 闭包和block很像,都是提前准备好代码
- block会对外部变量进行强引用,保证执行代码时变量还在
- block中用到self一定要小心
闭包
- 闭包也一样,会对外部变量进行强引用,保证执行代码时变量还在
- 如果你将闭包赋值给一个实例的属性,并且该闭包通过访问该实例或其成员而捕获了该实例,你将创建一个闭包和该实例件的循环强引用
- Swift开发中能不写self就不写self,一看到self就想到闭包
Objective-C中如何解决循环引用
- __weak typeof(self) weakSelf = self;
- 特点:对象释放后会自动将变量赋值为nil
- __unsafe _ unretained typeof(self) weakSelf = self;
- 特点:对象释放后不会自动将变量赋值为nil,指向一块废弃的存储空间
Swift中如何解决循环引用
- weak var weakSelf = self
- weak 相当于OC中 __weak,和OC一样,对象释放后会自动将变量赋值为nil
- 所以被weak修饰的变量是可选类型
- unowned var weakSelf = self
- unowned 相当于OC中 __unsafe _ unretained,和OC一样,对象释放后不会自动将变量赋值为nil
- 所以被unowned修饰的变量,不是可选类型
注意
weak和unowned只能修饰对象类型, 因为只有对象类型才有引用计数
应用
- 什么时候用weak
- 当被保存的对象有可能提前释放时就用weak
- 什么时候用unowned
- 当被保存的对象在使用时不会被提前释放时就用unowned
捕获列表
- 可以在
调用
闭包时在形参列表前面通过[ ]指定捕获列表, 告诉系统如何处理指定的这些值
使用实例
var callBack:(()->())?
var button:UIButton?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
// weak var weakSelf = self
// unowned var weakSelf = self
callBack = {[unowned self,weak btn = self.button] ()->() in
// self.view.backgroundColor = UIColor.red()
// weakSelf.view.backgroundColor = UIColor.red()
self.view.backgroundColor = UIColor.red
print(btn ?? "nil")
}
loadData(finished: callBack!)
}
func loadData(finished:@escaping ()->()) -> Void {
DispatchQueue.global().async {
print("子线程做耗时操作\(Thread.current)")
DispatchQueue.main.async {
print("主线程更新UI\(Thread.current)")
finished()
}
}
}
网友评论