Swift manages memory automatically. This means that you don’t have to actively free memory.
For example, the Bar contained in Foo can be released along with 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: Bar
init() {
bar = Bar()
}
deinit {
print("Foo exit")
}
}
class Bar {
deinit {
print("Bar exit")
}
}Copy the code
Executing this code prints:
Foo exit
Bar exitCopy the code
See that Foo and Bar are freed automatically. As a programmer, you don’t need to do any active memory freeing.
However, there is A special case, called two-way reference, in which when A is released, B needs to be freed, and B references A, so neither can be freed:
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")}}Copy the code
This code simply prints:
App exitCopy the code
At this point, all I need to do is set one of the bidirectional references to weak, which means that although I hold the reference, I don’t have to worry about the object’s release when I release it.
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) } } }Copy the code
Of course, you can’t do it without marking it, because the compiler won’t pass it, requiring that whenever self is referenced, it must mark it.