[swift]-閉包解決循環引用的三種寫法

1:定義一個閉包屬性:也是須要初始化的時候給它初始化值,若是沒有初始化值,就要把它聲明成可選類型json

var callBack : ((jsonData : String) -> ())?

2:請求代碼演示:swift

import UIKit

class HttpTools: NSObject {
    
    // 定義一個閉包屬性:也是須要初始化的時候給它初始化值,若是沒有初始化值,就要把它聲明成可選類型
    var callBack : ((jsonData : String) -> ())?
    
    
    // 閉包的類型:(參數列表) -> (返回值類型)
    func loadData(callBack : (jsonData : String) -> ()) {
        
        self.callBack = callBack  
        
        dispatch_async(dispatch_get_global_queue(0, 0)) {
            print("發送網絡請求\(NSThread.currentThread())")
            
            dispatch_sync(dispatch_get_main_queue(), { 
                print("獲取到數據,而且進行回調:\(NSThread.currentThread())")
                callBack(jsonData: "jsonData數據===================")
                
            })
        }
    }

}

 

3:循環引用網絡

> 寫法之一: weak var weakSelf = self;閉包

// weakSelf可能保存一個內存地址,也可能保存一個空地址:0x0地址
        weak var weakSelf = self;
        tools.loadData { (jsonData) in
            // weakSef?.view :
            // 若是前面的可選類型,沒有值,後面全部的代碼都不會執行
            // 若是前面的可選類型有值,系統會自動將咱們的weakself進行解包,而且使用weakSelf
            weakSelf?.view.backgroundColor = UIColor.redColor()
}
 */

 

> 寫法之二:優先推薦使用:多加了一個[weak self]:能夠說是對第一種方式的簡化版寫法async

/*解決循環引用的方式二(推薦使用這種方式)
        // 這樣寫僅僅是對方式1的一種簡化寫法
        tools.loadData {[weak self] (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            self?.view.backgroundColor = UIColor.redColor()
        }
*/

 

> 寫法之三:比較危險,容易產生壞內存訪問:就是對象銷燬後原來的指針仍是指向原來的對象,產生野指針  [unowned self]ide

//解決循環引用的方式三
        tools.loadData {[unowned self] (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            self.view.backgroundColor = UIColor.redColor()
 }

 

知識點補充:銷燬方法spa

// deinit至關於oc中的dealloc方法,當對象銷燬的時候會調用這個方法
    deinit{
        print("deinit---------");
    }

 

4:代碼演示 :指針

import UIKit

class ViewController: UIViewController {
    
    // 建立屬性的同時初始化對象
    var tools : HttpTools = HttpTools()
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        print("-----");
        
        /*解決循環引用的方式一
        // weakSelf可能保存一個內存地址,也可能保存一個空地址:0x0地址
        weak var weakSelf = self;
        tools.loadData { (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            // weakSef?.view :若是前面的可選類型,沒有值,後面全部的代碼都不會執行
            // 若是前面的可選類型有值,系統會自動將咱們的weakself進行解包,而且使用weakSelf
            weakSelf?.view.backgroundColor = UIColor.redColor()
        }
        */
        
        
        
        /*解決循環引用的方式二(推薦使用這種方式)
        // 這樣寫僅僅是對方式1的一種簡化寫法
        tools.loadData {[weak self] (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            self?.view.backgroundColor = UIColor.redColor()
        }
         */
        
        
        
        //解決循環引用的方式三
        tools.loadData {[unowned self] (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            self.view.backgroundColor = UIColor.redColor()
        }
        
    }
    
    
    // deinit至關於oc中的dealloc方法,當對象銷燬的時候會調用這個方法
    deinit{
        print("deinit---------");
    }
}

 

5:尾隨閉包:若是閉包做爲方法的最後一個參數,那麼()能夠省略掉code

三種寫法:對象

> 普通寫法:({

})

// 普通寫法
        tools.loadData ({[weak self] (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            self?.view.backgroundColor = UIColor.redColor()
        })

> 寫法之一:(){

}

// 寫法一
        tools.loadData () {[weak self] (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            self?.view.backgroundColor = UIColor.redColor()
        }

> 寫法之二:這是上面系統自動省略的那種方法

{

}

// 寫法二:系統默認會省略掉()寫法
        tools.loadData {[weak self] (jsonData) in
            print("拿到了json數據了:\(jsonData)")
            self?.view.backgroundColor = UIColor.redColor()
        }

 

 

 

 

意見反饋郵件:1415429879@qq.com 歡迎大家的閱讀和讚揚、謝謝!

相關文章
相關標籤/搜索