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