Swift是自動管理內存的。這意味著,你不需要主動釋放內存。
比如Foo內包含的Bar,可以隨同Foo一起被釋放:
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: Barinit() {bar = Bar()}deinit {print("Foo exit")}
}
class Bar {deinit {print("Bar exit")}
}復制代碼
執行此代碼,會打印:
Foo exit
Bar exit復制代碼
可見Foo和Bar都是自動釋放的。作為程序員,你不需要做任何內存的主動釋放。
但是,有一種特殊情況,叫做雙向引用,導致釋放A時,需要釋放B,而B又引用了A,那么兩個都無法被釋放:
class Foo {let bar: Barinit() {bar = Bar()bar.foo = self}deinit {print("Foo exit")}
}
class Bar {var foo: Foo? = nildeinit {print("Bar exit")}
}復制代碼
此代碼只會打印:
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]() inprint(self?.a)}}
}復制代碼
當然,不標記也是不行的,因為編譯器就不會通過,它要求只要引用了self,就必須標記。