內容目錄
一個”正常”物件(Object) 的生命週期
- Allocation: Takes memory from a stack or heap.
- Initialization:
init
code runs. - Usage.
- Deinitialization:
deinit
code runs. - Deallocation: Returns memory to a stack or heap. (If not, Memory Leak)
而Swift透過”自動算數 (ARC)”的機制來判斷物件是否還被使用: init
=> count + 1deinit
=> count – 1
什麼時候該為Object加上 weak / unowned?
兩個Object之間有關連,就會形成Reference(Strong / Weak / Unowned),沒特別宣告,Swift會認定為Strong。
Apple’s Documentation recommends that a parent object should have a strong hold on a child object by convention — not the other way around.
class Parent {
var child: Child?
}
class Child {
unowned var parent: Parent
}
Capture Lists
var x = 5
var y = 5
let someClosure = { [x] in
// [x] <---- 這個就是Capture Lists
print("\(x), \(y)")
}
x = 6
y = 6
someClosure() // Prints 5, 6
print("\(x), \(y)") // Prints 6, 6
Cycles with Value Types & Reference Types
Value Types之間不會存在Cycles,Compile也不會過,例如:
// struct is a value type
struct Node {
var payload = 0
var next: Node? // <-- compile error!
}
// class is a reference type
class Node {
var payload = 0
var next: Node? // --> it is ok!
}
// what if ...
class Person {
var name: String
var friends: [Person] = [] // <-- compiled but not deallocated
// unowned var friends: [Person] = [] // <-- and it's not allowed to use unowned
}
// we need to create a generic wrapper
class Unowned<T: AnyObject> {
unowned var value: T
init (_ value: T) {
self.value = value
}
}
class Person {
var name: String
var friends: [Unowned<Person>] = [] // <-- wrap 'Person'
}