单例对象分配在哪里?
Where Singleton object is allocated?
我想知道 myClass
对象的准确分配位置,所以我画了分配流程
class MyClass {
static let shared = MyClass()
private init() { }
}
let myClass = MyClass.shared
myClass
常量分配在堆栈中
myClass
常量指向分配了 MyClass
的堆
MyClass.shared
static 属性 指向 MyClass()
在堆中分配的位置
这个流程对吗?我是不是误会了什么?
Swift在数据段为MyClass.shared
分配存储,初始化为nil。数据段的布局和初始内容由可执行文件定义。从历史上看,堆在数据段的末尾立即开始,但在具有地址 space 布局随机化 (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
或元组)或始终在堆上(在 class
或 actor
的情况下)。
如果myClass
是一个函数中的局部变量,那么它被存储在堆栈中。
我想知道 myClass
对象的准确分配位置,所以我画了分配流程
class MyClass {
static let shared = MyClass()
private init() { }
}
let myClass = MyClass.shared
myClass
常量分配在堆栈中myClass
常量指向分配了MyClass
的堆MyClass.shared
static 属性 指向MyClass()
在堆中分配的位置
这个流程对吗?我是不是误会了什么?
Swift在数据段为
MyClass.shared
分配存储,初始化为nil。数据段的布局和初始内容由可执行文件定义。从历史上看,堆在数据段的末尾立即开始,但在具有地址 space 布局随机化 (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
或元组)或始终在堆上(在class
或actor
的情况下)。如果
myClass
是一个函数中的局部变量,那么它被存储在堆栈中。