ARC(自动引用计数)实战
ARC(Automatic Reference Counting) in Action
我目前正在关注Apple Documentation。这是我的问题:
class Person {
let name: String
init(name: String) {
self.name = name
println("\(name) is being initialized")
}
deinit {
println("\(name) is being deinitialized")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var reference1: Person?
var reference2: Person?
var reference3: Person?
reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized
reference2 = reference1
reference3 = reference1
reference1 = nil
reference2 = nil
}
}
在 reference1
等于 nil
之后,ARC 释放实例并打印 "John Appleseed is being deinitialized"
不应该在reference3 = nil
之后解除分配吗?
它正在释放,因为编译器能够识别不再使用本地创建的对象。例如在下面的代码中执行 viewDidLoad
方法后 Person
将被释放,因为将来没有人使用 person 对象。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.\
var reference1: Person?
var reference2: Person?
var reference3: Person?
reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized
reference2 = reference1
reference3 = reference1
reference1 = nil
reference2 = nil
// println(reference3?.name)
}
如果要保留对象,则需要将 reference3
创建为 property
,如下所示:
class ViewController: UIViewController {
var reference3 : Person?
override func viewDidLoad() {
super.viewDidLoad()
var reference1: Person?
var reference2: Person?
reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized
reference2 = reference1
reference3 = reference1
reference1 = nil
reference2 = nil
// println(reference3?.name)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
println(reference3?.name)
}
}
这里的问题是范围问题。我们可以通过断点来了解更多。
在这里,我们在初始化 reference1
之前停止了。
所有变量都是预期的 nil
:
然后 reference1
初始化之后?
好的,让我们跳到设置 reference2
和 reference3
之后:
所有三个变量都指向相同的内存位置,我们只能看到初始化程序 运行 一次。这些都指向同一个位置。
让我们向前走:
reference1
现在指向 None
。是nil
。 deinit
mm 方法尚未被调用并打印其消息。
让我们更进一步:
现在 reference1
和 reference2
都是预期的 nil
。调用了我添加的 println
语句。但是 deinit
没有 运行 并且 reference3
不是 nil
.
下一步是逐步退出方法。一旦我们离开方法,变量就超出范围并且 deinit
被调用:
我目前正在关注Apple Documentation。这是我的问题:
class Person {
let name: String
init(name: String) {
self.name = name
println("\(name) is being initialized")
}
deinit {
println("\(name) is being deinitialized")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var reference1: Person?
var reference2: Person?
var reference3: Person?
reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized
reference2 = reference1
reference3 = reference1
reference1 = nil
reference2 = nil
}
}
在 reference1
等于 nil
之后,ARC 释放实例并打印 "John Appleseed is being deinitialized"
不应该在reference3 = nil
之后解除分配吗?
它正在释放,因为编译器能够识别不再使用本地创建的对象。例如在下面的代码中执行 viewDidLoad
方法后 Person
将被释放,因为将来没有人使用 person 对象。
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.\
var reference1: Person?
var reference2: Person?
var reference3: Person?
reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized
reference2 = reference1
reference3 = reference1
reference1 = nil
reference2 = nil
// println(reference3?.name)
}
如果要保留对象,则需要将 reference3
创建为 property
,如下所示:
class ViewController: UIViewController {
var reference3 : Person?
override func viewDidLoad() {
super.viewDidLoad()
var reference1: Person?
var reference2: Person?
reference1 = Person(name: "John Appleseed")
// prints "John Appleseed is being initialized
reference2 = reference1
reference3 = reference1
reference1 = nil
reference2 = nil
// println(reference3?.name)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
println(reference3?.name)
}
}
这里的问题是范围问题。我们可以通过断点来了解更多。
在这里,我们在初始化 reference1
之前停止了。
所有变量都是预期的 nil
:
然后 reference1
初始化之后?
好的,让我们跳到设置 reference2
和 reference3
之后:
所有三个变量都指向相同的内存位置,我们只能看到初始化程序 运行 一次。这些都指向同一个位置。
让我们向前走:
reference1
现在指向 None
。是nil
。 deinit
mm 方法尚未被调用并打印其消息。
让我们更进一步:
现在 reference1
和 reference2
都是预期的 nil
。调用了我添加的 println
语句。但是 deinit
没有 运行 并且 reference3
不是 nil
.
下一步是逐步退出方法。一旦我们离开方法,变量就超出范围并且 deinit
被调用: