【问题标题】:Where Singleton object is allocated?单例对象分配在哪里?
【发布时间】:2021-11-28 20:54:40
【问题描述】:

我想知道myClass对象的确切分配位置,所以我画了分配流程

class MyClass {
    static let shared = MyClass()
    private init() { }
}

let myClass = MyClass.shared 
  1. myClass 常量在堆栈中分配

  2. myClass 常量指向分配MyClass 的堆

  3. MyClass.shared 静态属性指向在堆中分配的MyClass()

这个流程对吗?我是不是误会了什么?

【问题讨论】:

    标签: swift memory singleton allocation


    【解决方案1】:
    • Swift 为数据段中的MyClass.shared 分配存储空间,初始化为 nil。数据段的布局和初始内容由可执行文件定义。从历史上看,堆在数据段的末尾立即开始,但在具有地址空间布局随机化 (ASLR) 的现代 64 位系统上,我不知道这是否仍然正确。

    • Swift还在数据段中分配了一个swift_once_t来记录MyClass.shared是否已经被初始化。

    • Swift 在代码段中为MyClass.shared 生成一个getter 函数。 getter 函数在第一次调用 getter 时使用swift_once_t 来初始化MyClass.shared 的存储。大概是这样的:

      var _storage_MyClass_shared: MyClass? = nil
      var _once_MyClass_shared: swift_once_t = .init() // essentially, false
      
      func _getter_MyClass_shared() -> MyClass {
          swift_once(&_once_MyClass_shared, {
              _storage_MyClass_shared = MyClass()
          })
          return _storage_MyClass_shared!
      }
      
    • MyClass 的实例存储在堆上。它以包含isa 指针(指向MyClass 元数据)的单词开头,然后是包含(通常)引用计数的单词,然后是对象实例变量的存储。在您的情况下,没有实例变量,因此没有额外的存储空间。图中标有Myclass() 的蓝色框和指向它的箭头不存在。

    • 如果myClass 位于顶层(不在方法或数据类型声明中),那么它也会与另一个跟踪它是否已被初始化的swift_once_t 一起存储在数据段中,并且 Swift 会生成一个 getter在代码段中为它。

    • 如果myClass 是一个数据类型的实例变量,那么它将作为其包含对象的一部分存储,该对象可能位于堆栈或堆上(在struct 的情况下,enum ,或元组)或始终在堆上(在classactor 的情况下)。

    • 如果myClass 是函数中的局部变量,则将其存储在堆栈中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 2018-10-14
      • 2014-08-17
      • 1970-01-01
      • 2011-09-19
      • 2020-06-18
      • 1970-01-01
      相关资源
      最近更新 更多