Swift iOS : 內存管理

Swift是自動管理內存的。這意味着,你不須要主動釋放內存。javascript

好比Foo內包含的Bar,能夠隨同Foo一塊兒被釋放:java

import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window : UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        Foo()
        return true
    }
}
class Foo {
    let bar: Bar
    init() {
        bar = Bar()
    }
    deinit {
        print("Foo exit")
    }
}
class Bar {
    deinit {
        print("Bar exit")
    }
}複製代碼

執行此代碼,會打印:程序員

Foo exit
Bar exit複製代碼

可見Foo和Bar都是自動釋放的。做爲程序員,你不須要作任何內存的主動釋放。app

可是,有一種特殊狀況,叫作雙向引用,致使釋放A時,須要釋放B,而B又引用了A,那麼兩個都沒法被釋放:spa

class Foo {
    let bar: Bar
    init() {
        bar = Bar()
        bar.foo = self
    }

    deinit {
        print("Foo exit")
    }
}
class Bar {
    var foo: Foo? = nil
    deinit {
        print("Bar exit")
    }
}複製代碼

此代碼只會打印:code

App exit複製代碼

此時,須要作的就是把這個雙向引用中的一個設置爲weak,表示的意思是儘管我持有這個引用,可是釋放的時候,卻無需考慮此對象的釋放。對象

import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window : UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        Baz()
        print("App exit")
        return true
    }
}
typealias Bar = (()->Void)
class Foo {
    func work(_ bar : Bar) {
        bar()
    }

    deinit {
        print("Foo exit")
    }
}
class Baz {
    var a : String?
    init (){
        a = "1"
        let f = Foo()
        f.work(){[weak self]() in
            print(self?.a)
        }
    }
}複製代碼

固然,不標記也是不行的,由於編譯器就不會經過,它要求只要引用了self,就必須標記。ip

相關文章
相關標籤/搜索