swift2.0 學習筆記Thirteen

import UIKit



class ViewController: UIViewController {

   

    override func viewDidLoad() {

        super.viewDidLoad()

        //閉包引起的循環強引用

        //循環強引用還會發生在當你將一個閉包賦值給類實例的某個屬性,並且這個閉包體中又使用了這個類實例。這個閉包體中可能訪問了實例的某個屬性,例如self.someProperty,或者閉包中調用了實例的某個方法,例如self.someMethod.這兩種情況都導致了閉包捕獲self,從而產生循環強引用

        //循環引用的產生,是因爲閉包和類相似,都是引用類型。當你把一個引用賦值給了閉包。實質上,這兩個強引用讓彼此一直有效。但是和兩個類實例不同的是一個是類實例另一個是閉包。

        var paragraph:HTMLElement?=HTMLElement(name: "P", text: "hello world")

        print(paragraph!.asHTML())//P hello world P

       //HTMLElement類產生了類實例和asHTML默認值的閉包之間的循環強引用

       /*

        {

        if let text = self.text {

        return "\(self.name) \(text) \(self.name)"

        }else{

        return "\(self.name)"

        }

        }該閉包引用了self即強引用了HTMLElement實例,

        lazy var asHTML: Void->String該變量又強引用了閉包

         */

        paragraph=nil  //不會觸發deinit析構函數

        

        //解決閉包引起的循環強引用

        //在定義閉包時同時定義捕獲列表作爲閉包的一部分,通過這種方式可以解決閉包和類實例之間的循環強引用。捕獲列表定義了閉包體內捕獲一個或者多個引用類型的規則

        //捕獲列表中的每一項都由一對元素組成,一個元素是weakunowned關鍵字,另一個元素是類實例的引用。這些項在方括號中用逗號分開

        //如果閉包有參數列表和返回類型,把捕獲列表放在它們前面

      

        var paragraph2:HTMLElement?=HTMLElement(name: "P", text: "hello world")

        print(paragraph2!.asHTML2())//P hello world P

                                    //P is being deinit

        //注意:如果被捕獲的引用絕對不會變爲nil,應該用無主引用,而不是弱引用,弱引用總是可選類型,並且當引用的實例被銷燬後,弱引用的值會自動置爲nil

    }

   

}

class HTMLElement{

    lazy var asHTML2: Void->String = {

        [unowned self] in           //用無主引用而不是強引用來捕獲self

        if let text = self.text {

            return "\(self.name) \(text) \(self.name)"

        }else{

            return "\(self.name)"

        }

    }

    let name:String

    let text:String?

    lazy var asHTML: Void->String = {

        if let text = self.text {

            return "\(self.name) \(text) \(self.name)"

        }else{

            return "\(self.name)"

        }

    }

    init(name:String,text:String?=nil){

        self.name=name;

        self.text=text;

    }

    deinit{

        print("\(name) is being deinit")

    }

    

}

//lazy var someClosure: Void -> String = {

//    [unowned self, weak delegate = self.delegate!] in

//    // closure body goes here

//}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章