循环引用场景描述
有两个类HttpTool类和ViewController类,ViewController有HttpTool属性,HttpTool中有callBack类型的闭包做属性;
即ViewController引用了HttpTool实例,HttpTool里引用了callBack,callBack的实现方法中又调用了self.view(ViewController.view)造成了循环引用
class HttpTool: NSObject {
var callBack:((String)->())?
func loadData (callBack:@escaping((String)->())){
DispatchQueue.global().async {
DispatchQueue.main.async {
callBack("json数据")
self.callBack = callBack;
}
}
}
}
class ViewController: UIViewController {
let too:HttpTool = HttpTool()
override func viewDidLoad() {
super.viewDidLoad()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// 闭包去循环引用方法一
weak var weakSelf = self;
too.loadData { (jsonData:String) in
print(jsonData)
/*
weakSelf?view
如果前边的可选类型,没有值,后边的代码不会执行
如果前边的可选类型,有值,系统会自动将weakSelf进行解包,并且使用weakSelf
**/
weakSelf?.view.backgroundColor = UIColor.red
}
//闭包去循环引用方式二 [unowned self] 下边self不用写?,self如果没值,下边会发生崩溃
// /*
// __weak 与__unsafe_unretained的区别
// __weak指向的对象一旦被销毁,则指针会指向nil(0x00)
// __unsafe_unretained依然指向之前对象的内存地址,会造成野指针
// oc中的__unsafe_unreatined相当于swift中的unowned,故unowned
// **/
too.loadData {[unowned self](jsonData:String) in
print(jsonData)
/*
weakSelf?view
如果前边的可选类型,没有值,后边的代码不会执行
如果前边的可选类型,有值,系统会自动将weakSelf进行解包,并且使用weakSelf
**/
self.view.backgroundColor = UIColor.red
}
//闭包去循环引用方式三 [weak self]方法是方法一的简略形式
too.loadData {[weak self](jsonData) in
print(jsonData)
/*
weakSelf?view
如果前边的可选类型,没有值,后边的代码不会执行
如果前边的可选类型,有值,系统会自动将weakSelf进行解包,并且使用weakSelf
**/
self?.view.backgroundColor = UIColor.red
}
}
最常用的是方法三
swift中判定某对象是否销毁的依据是看该类的deinit方法是否执行了,相当于oc的dealloc方法