【发布时间】:2023-03-28 09:04:01
【问题描述】:
我有一个 Person 类如下:
class Person{
var name: String?
init(name: String){
self.name = name
}
func doWithDelay(){
let when = DispatchTime.now() + 2
DispatchQueue.main.asyncAfter(deadline: when) { [weak self] in
self?.name = "delayed"
print(self?.name )
}
}
deinit {
print("Person class is deinited \(self)")
}
}
我在下面的 viewController 中创建了一个Person 的实例:
class ViewController: UIViewController {
var p1 :Person? = Person(name: "MMM")
override func viewDidLoad() {
super.viewDidLoad()
var persons : [Person] = []
p1!.doWithDelay()
persons.append(p1!)
var p3 = Person(name: "OOO") // AAA
persons.removeAll()
}
}
如果我有var p3 = Person(name: "OOO"),那么我的p1 实例将 被释放,但是如果我注释掉AAA 行或简单地用var p3 = "howareyou" 替换它,那么我的实例Person 实例根本不会被释放。
为什么?!
【问题讨论】:
-
行为的哪一部分令人惊讶?如果您有
var p3 = Person,则该人将被解除分配。如果你不这样做,就没有什么可以释放的了。在任何一种情况下,您的实例var p1都不会在控制器释放之前被释放,因为控制器正在持有它。 -
回应您最近的编辑:不,您的
p1实例没有被释放。p3是,因为它是一个局部变量。尝试打印deinit中的人名。 -
@ConnorNeville ????谢谢。是的,我在想
p1正在被释放。还有一个问题。我刚刚将p3附加到persons,但它仍然被释放。persons不是应该坚持p3吗?我已经阅读了所有关于ARC...据我了解的是:persons将增加p3的保留计数,但不确定之后会发生什么。 -
@Honey
persons也是一个局部变量,因此将在方法范围的末尾取消初始化,因此减少其所有元素的保留计数,从而允许您的p3实例被释放。