解析Swift中閉包的循環引用
1.什麼時候會發生循環引用
原理跟OC中的block類似, 當有個屬性記錄下了函數傳遞回來的閉包, 産生強引用, 就會發生閉包的循環引用
2.怎麼解決循環引用
如何解決閉包的循環引用, 同樣有三種方式:
- 使用weak修飾變量, 打破強引用, 因為使用weak修飾的變量有一次變成nil的機會
- 使用[weak self] 修飾閉包,原理跟__weak類似, 這樣在閉包中使用self, 就是弱引用
- 使用[unowned self ] 修飾閉包, 跟__unsafe_unretained類似, 不安全
3.如何判斷是否發生強引用, 閉包中使用析構函數
- 代碼:
//swift dealloc
//析構函數
deinit{
print("銷毀")
}
- storyboard:
748058-d28cabf10ff73b50.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
//加載資料
dispatch_async(dispatch_get_global_queue(, )) { () -> Void in
print("執行耗時操作")
dispatch_async(dispatch_get_main_queue(), { () -> Void in
//執行回調
self.working()
})
}
}
func working() {
self.finishedCallBack?(dataString: "<html>")
}
//swift dealloc
//析構函數
deinit {
print("銷毀")
}
}