【问题标题】:Does ARC deallocate a class if deinit has been declared or does it maintain the reference?如果 deinit 已被声明,ARC 是否会释放一个类或它是否维护引用?
【发布时间】:2022-01-02 04:36:13
【问题描述】:

我正在尝试使用 ARC 以及它处理内存释放的方式。如果我有一些课:

class Person {
      var name: String = ""
      var age: Int = 0

      init(name: String, age: Int) {
         self.name = name
         self.age = age
     }

     deinit {
         print("Person \(name) has been deallocated")
     }
}



class MyViewController: UIViewController {
    var person = Person(name: "Steve", age: 85)
}

我是否需要担心为该人腾出空间,还是由 ARC 处理?我需要在MyViewController 中声明deinit 吗?

【问题讨论】:

标签: swift memory-management automatic-ref-counting


【解决方案1】:

一旦引用对象本身被解除分配,ARC 就会为您处理解除初始化和解除分配。引用https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html:

...ARC 跟踪当前引用每个类实例的属性、常量和变量的数量。只要至少一个对该实例的活动引用仍然存在,ARC 就不会释放该实例。

...每当您将类实例分配给属性、常量或变量时,该属性、常量或变量都会对实例进行强引用。该引用被称为“强”引用,因为它牢牢控制该实例,并且只要该强引用仍然存在,就不允许释放它。

您的代码也证明了这一点:如果我将您的代码复制到 Playground 并添加 MyViewController() 以创建该类的实例,我会在程序退出之前在控制台输出中看到 Person Steve has been deallocated

【讨论】:

  • 关于您的出色回答的一点澄清:系统并不总是在终止您的应用程序之前释放和释放您的对象。如果您的应用被暂停,然后在暂停时终止,则它可能不会在应用终止之前释放/释放其对象。
  • (playground 的生命周期与应用程序的生命周期完全不同,因此您必须小心使用 Playground 作为测试应用程序的一种方式。)
  • 确实如此。我也没有提到自动释放池,这会导致延迟释放。
  • 您不需要在编写的代码中做任何不同的事情。应用程序终止可能并不理想,但它们并非完全出乎意料,并且系统可能会在认为必要时终止您的应用程序:developer.apple.com/documentation/xcode/… 我要补充一点,您的deinitializers 在异常期间可能不会运行或强制终止,但我希望它们在系统首先调用applicationWillTerminate的正常情况下运行。
  • ARC 的要点是您不需要考虑分配和释放,因为编译器和运行时会为您管理引用计数并在没有引用时释放(垃圾收集的一种形式)。您只需要考虑强引用和弱引用并确保对象图中没有retain cycles。如果你发现你需要更多的控制,你可以使用明确的autoreleasepools,并在你使用完一个对象后设置对nil的可选引用。
猜你喜欢
  • 1970-01-01
  • 2012-02-06
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多