Reputation: 51
I wanted to know where myClass
objects allocated exactly so I drew allocation flow
class MyClass {
static let shared = MyClass()
private init() { }
}
let myClass = MyClass.shared
myClass
constant is allocated in Stack
myClass
constant point to Heap where MyClass
is allocated
MyClass.shared
static property point to MyClass()
where allocated in Heap
Is this flow right? Am I misunderstood something?
Upvotes: 1
Views: 807
Reputation: 385870
Swift allocates storage for MyClass.shared
in the data segment, initialized to nil. The data segment's layout and initial contents are defined by the executable file. Historically, the heap started immediately at the end of the data segment, but on modern 64-bit systems with address space layout randomization (ASLR), I don't know if that's still true.
Swift also allocates a swift_once_t
in the data segment to record whether MyClass.shared
has been initialized yet.
Swift generates a getter function for MyClass.shared
in the code segment. The getter function uses the swift_once_t
to initialize the storage of MyClass.shared
the first time the getter is called. It looks approximately like this:
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!
}
The instance of MyClass
is stored on the heap. It starts with a word containing the isa
pointer (to the MyClass
metadata), followed by a word containing (usually) reference counts, followed by storage for the object's instance variables. In your case, there are no instance variables, so there is no additional storage. The blue box labeled Myclass()
in your diagram, and the arrow pointing to it, do not exist.
If myClass
is at top-level (not inside a method or data type declaration), then it is also stored in the data segment along with another swift_once_t
that tracks whether it's been initialized, and Swift generates a getter for it in the code segment.
If myClass
is an instance variable of a data type, then it is stored as part of its containing object, which may be either on the stack or the heap (in the case of a struct
, enum
, or tuple) or always on the heap (in the case of a class
or actor
).
If myClass
is a local variable in a function, then it is stored on the stack.
Upvotes: 2