内存管理:使用 weak var 的保留循环,使用 unowned 的非保留循环。为什么?
Memory management: retain cycle with weak var, non retain cycle with unowned. Why?
TL;DR
我有一个结构和一个 class。该结构具有对 class 实例的引用,并且该对象具有捕获该结构的闭包。
如果对对象的引用是 unowned ,那么它们似乎都被取消了初始化。如果对对象的引用是 weak 它们会相互保留。
为什么?
我有一个结构和一个 class 可以相互引用,我试图找出保留周期和打破它们的方法。所以我玩了一下playground。
鉴于此代码:
struct A {
unowned var b: B
init(b: B) {
self.b = b
}
func setup() {
print("A setup")
b.didSomethingClosure = {
print("A: b did do something")
self.printSomething()
}
}
func printSomething() {
print("A: A did do something")
}
}
class B {
var didSomethingClosure:(() -> Void)?
func doSomething() {
print("B: do something")
didDoSomething()
}
func didDoSomething() {
print("B: did something")
if let closure = didSomethingClosure {
closure()
}
}
deinit {
print("B: deinit")
}
}
do {
let b = B()
let a = A(b: b)
a.setup()
b.doSomething()
print("end do")
}
如果struct中的var b声明为unowned var b: B
,则释放B对象。如果我将代码修改为weak var b: B?
,然后修改为b?.didSomethingClosure = ...
,则B对象被保留。为什么?
我想问题是你 运行 它在 Playground
中。尝试在真正的应用程序中 运行 它,你会看到 B
被释放
struct A {
weak var b: B?
init(b: B) {
self.b = b
}
func setup() {
print("A setup")
b?.didSomethingClosure = {
print("A: b did do something")
self.printSomething()
}
}
func printSomething() {
print("A: A did do something")
}
}
class B {
var didSomethingClosure:(() -> Void)?
func doSomething() {
print("B: do something")
didDoSomething()
}
func didDoSomething() {
print("B: did something")
if let closure = didSomethingClosure {
closure()
}
}
deinit {
print("B: deinit")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let b = B()
let a = A(b: b)
a.setup()
b.doSomething()
print("end do") // B is deallocated here
}
}
TL;DR
我有一个结构和一个 class。该结构具有对 class 实例的引用,并且该对象具有捕获该结构的闭包。 如果对对象的引用是 unowned ,那么它们似乎都被取消了初始化。如果对对象的引用是 weak 它们会相互保留。 为什么?
我有一个结构和一个 class 可以相互引用,我试图找出保留周期和打破它们的方法。所以我玩了一下playground。
鉴于此代码:
struct A {
unowned var b: B
init(b: B) {
self.b = b
}
func setup() {
print("A setup")
b.didSomethingClosure = {
print("A: b did do something")
self.printSomething()
}
}
func printSomething() {
print("A: A did do something")
}
}
class B {
var didSomethingClosure:(() -> Void)?
func doSomething() {
print("B: do something")
didDoSomething()
}
func didDoSomething() {
print("B: did something")
if let closure = didSomethingClosure {
closure()
}
}
deinit {
print("B: deinit")
}
}
do {
let b = B()
let a = A(b: b)
a.setup()
b.doSomething()
print("end do")
}
如果struct中的var b声明为unowned var b: B
,则释放B对象。如果我将代码修改为weak var b: B?
,然后修改为b?.didSomethingClosure = ...
,则B对象被保留。为什么?
我想问题是你 运行 它在 Playground
中。尝试在真正的应用程序中 运行 它,你会看到 B
被释放
struct A {
weak var b: B?
init(b: B) {
self.b = b
}
func setup() {
print("A setup")
b?.didSomethingClosure = {
print("A: b did do something")
self.printSomething()
}
}
func printSomething() {
print("A: A did do something")
}
}
class B {
var didSomethingClosure:(() -> Void)?
func doSomething() {
print("B: do something")
didDoSomething()
}
func didDoSomething() {
print("B: did something")
if let closure = didSomethingClosure {
closure()
}
}
deinit {
print("B: deinit")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let b = B()
let a = A(b: b)
a.setup()
b.doSomething()
print("end do") // B is deallocated here
}
}