对Deinit和内存泄漏感到困惑

时间:2017-10-03 11:43:58

标签: ios swift memory-management memory-leaks

我正在尝试了解iOS开发中的内存管理。我读了这篇文章/教程:Make Memory Management Great Again

在该教程中,类中有一个deinit方法,如下所示:

class Human {
  var passport: Passport?
  let name: String

  init(name: String) {
    self.name = name
  }

  deinit {
    print("I'm gone, friends")
  }
}

在我们创建实例之后,引用计数是1,因为它是一个强引用。直到这一步,我明白了。

var bob: Human? = Human(name: "Bob Lee")

据说当我们创建一个实例时,它实际上占用了我们的RAM空间。

如果我们将nil分配给' bob'变量,deinit将打印("我已经离开,朋友"),并且关系不再存在,因此引用计数变为0,这导致两个对象都被解除分配。

令我困惑的事情:

  1. 在我的实际代码中/从我关注的教程中,我从未见过' deinit'在我的班级中,我从不将nil分配给实例,因此该对象永远不会被释放,并且它会在我的记忆中像胖子一样占用空间?我应该在代码中写deinit吗?因为我认为如果空间有限,就会被数据对象填满,最终我的应用程序会崩溃

  2. 据说:

  3.   

    自动引用计数以指示对象是否仍然是   正在使用或不再需要

    不再需要?这是什么意思?

1 个答案:

答案 0 :(得分:1)

只是为了澄清你的例子:

var bob: Human? = Human(name: "Bob Lee")
// bob now has a reference count of 1
// the memory at the bob location is ready to access and/or modify
// this means bob is still alive and we can find out things about him

print(bob!.name) 
// prints "Bob Lee"

bob = nil
// deinit called, "I'm gone, friends"
// bob now has a reference count of 0, and ARC has released the object that was stored here
// we cannot find out anything about bob
// the memory at the location of bob is now released

print(bob!.name)
// Error: Unexpectedly found nil while unwrapping optional value

回答你的问题:

  1. 如果您永远不需要将nil分配给bob(根据上下文可能没有意义),您应该将bob的类型指定为{{ 1}},而不是Human。这意味着鲍勃永远不会,也永远不会是零,并使您的代码更容易推理。 意味着位于Human?的{​​{1}}对象永远不会从内存中消失。例如,如果Human位于视图控制器中,在某个时刻被解除分配(如果用户导航离开该VC或应用程序已关闭),bob当然也将被释放。系统

  2. “不再需要”表示从代码的访问角度来看“需要”。如果bob设置为nil,为什么还需要再次访问有关他的信息?你不这样做,所以位于bob的对象的引用数减少到0,不再需要,并且被释放。

  3. 我希望我能为你清楚一些事情。