1.什么時(shí)候會(huì)發(fā)生循環(huán)引用
原理跟OC中的block類似, 當(dāng)有個(gè)屬性記錄下了函數(shù)傳遞回來的閉包, 產(chǎn)生強(qiáng)引用, 就會(huì)發(fā)生閉包的循環(huán)引用
2.怎么解決循環(huán)引用
如何解決閉包的循環(huán)引用, 同樣有三種方式:
使用weak修飾變量, 打破強(qiáng)引用, 因?yàn)槭褂脀eak修飾的變量有一次變成nil的機(jī)會(huì)
使用[weak self] 修飾閉包原理跟__weak類似, 這樣在閉包中使用self, 就是弱引用
使用[unowned self ] 修飾閉包, 跟__unsafe_unretained類似, 不安全
3.如何判斷是否發(fā)生強(qiáng)引用, 閉包中使用析構(gòu)函數(shù)
//swift dealloc
//析構(gòu)函數(shù)
deinit{
print("銷毀")
}
- storyboard:

748058-f7ffe3d95b622696.png
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
//加載數(shù)據(jù)
dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
print("執(zhí)行耗時(shí)操作")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//執(zhí)行回調(diào)
self.working()
})
}
}
func working() {
self.finishedCallBack?(dataString: "<html>")
}
//swift dealloc
//析構(gòu)函數(shù)
deinit {
print("銷毀")
}
}