Swift中strong,weak,unowned關(guān)鍵字

  • strong:當(dāng)你聲明一個屬性時,它默認(rèn)就是強引用
  • weak:弱引用對象的引用計數(shù)不會+1, 必須為可選類型變量

在聲明弱引用對象是必須用var關(guān)鍵字, 不能用let.
因為弱引用變量在沒有被強引用的條件下會變?yōu)閚il, 而let常量在運行的時候不能被改變.

class XDTest {
    //會報錯
    weak let tentacle = Tentacle() //let is a constant! All weak variables MUST be mutable.
}
  • unowned:相當(dāng)于__unsafe_unretained, 不安全. 必須為非可選類型.

unowned引用是non-zeroing(非零的), 在ARC銷毀內(nèi)存后,不會被賦為nil, 這表示著當(dāng)一個對象被銷毀時, 它指引的對象不會清零. 也就是說使用unowned引用在某些情況下可能導(dǎo)致dangling pointers(野指針). 所以在訪問無主引用的時候,要確保其引用正確,不然會引起內(nèi)存崩潰.

  • 隱式解析可選類型 :語法是在變量后面加上感嘆號(例如var name:String!). 在初始的時候可以為nil, 但是第一次賦值以后便會一直有值. 使用該類型只需要正常調(diào)用, 不需要像可選類型那樣解包.
避免在閉包中循環(huán)引用

在閉包中, 要拿到對象本身的屬性, 必須要用到self關(guān)鍵字.
導(dǎo)致block對對象進行了強引用, 而對象本身對block也是強引用, 這樣就形成了循環(huán)引用. (Self <-> Block)

  1. 解決辦法和OC中一樣, 將強引用self變?yōu)槿跻胹elf.
    OC中解決辦法是__weak SelfClass *weakSelf = self;
    在Swift中類似的解決辦法是(解決方式一)weak var weakSelf = self
  2. 使用捕獲列表(在其定義的上下文中捕獲常量或變量, 即使定義這些常量和變量的原域已經(jīng)不存在, 閉包仍然可以在閉包函數(shù)體內(nèi)引用和修改這些值.)

蘋果官方語言指南要求如果閉包和其捕獲的對象相互引用, 應(yīng)該使用unowned, 這樣可以保證他們會同時被銷毀. 大概是為了避免對象被釋放后維護weak引用空指針的開銷.

格式:在閉包前面加上[unowned 想要捕獲的變量]

官方文檔中的例子:
有參數(shù)和返回值的block

lazy var someClosure: (Int, String) -> String = {
    [unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
    // closure body goes here
}

無參數(shù)和返回值的block

lazy var someClosure: Void -> String = {
    [unowned self, weak delegate = self.delegate!] in
    // closure body goes here
}

例子:

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中 有特殊的寫法  [weak self]
        loadData { [weak self] (dataString) -> () in

            //以后在閉包中中 使用self 都是若引用的
            print("\(dataString) \(self?.view)")
        }
    }

    func method1() {
        // 解決方式一: weak , OC中類似方法__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í)行耗時操作")

            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("銷毀")
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容