swift 閉包迴圈引用的解決辦法
阿新 • • 發佈:2019-01-07
模擬網路請求,封裝工具類,使用閉包變數對閉包進行強引用
在控制器中呼叫工具類,在閉包內使用self會造成迴圈引用,使用三種方法可以解決閉包的迴圈引用// // NetworkRequestTool.swift // Test // // Created by fe on 2017/2/28. // Copyright © 2017年 fe. All rights reserved. // import UIKit class NetworkRequestTool: NSObject { var callBack:((_ jisonData:String)->())? = nil //定義閉包變數 //閉包型別:(引數列表)->(返回值型別) func loadData(callBack:@escaping (_ jisonData:String)->()) { //在這裡對callBack閉包進行強引用,如果以後在控制器中在閉包內用到self則會造成迴圈引用 self.callBack = callBack; DispatchQueue.global().async {//非同步全域性佇列 print("耗時操作\(Thread.current)") DispatchQueue.main.sync {//主佇列回掉 callBack("jisonData") } } } }
// // ViewController.swift // Test // // Created by fe on 2017/2/28. // Copyright © 2017年 fe. All rights reserved. // import UIKit class ViewController: UIViewController { let requestTool = NetworkRequestTool() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { /* //第一種解決閉包迴圈引用的方法 weak var weakSelf = self //weakSelf?.view.backgroundColor = UIColor.red (1)如果前面的可選型別,沒有值,後面的程式碼不會執行 (2)如果前面的可選型別,有值,系統會自動將weakSelf進行解包,並使用weakSelf weak var weakSelf = self requestTool.loadData { (String) in print("----------\(String)") weakSelf?.view.backgroundColor = UIColor.red } */ /* //第二種解決閉包迴圈引用的用法 [weak self] requestTool.loadData {[weak self] (String) in print("----------\(String)") self?.view.backgroundColor = UIColor.red } */ //第三種解決閉包迴圈引用的用法 [unowned self] //__weak :OC的關鍵字,__weak修飾的弱引用,如果指向的物件銷燬,那麼指標會立馬指向nil(0x0) //__unsafe_unretained :OC的關鍵字,__unsafe_unretained修飾的弱引用,如果指向的物件銷燬,那麼指標依然指向以前的記憶體地址,很容易產生“野指標”/“殭屍物件” //unowned :swift關鍵字,和OC的__unsafe_unretained關鍵字類似 requestTool.loadData {[unowned self] (String) in print("----------\(String)") self.view.backgroundColor = UIColor.red } } deinit { print("-----------deinit") } }