14. Когда value type оказывается в куче, а не на стеке?
Дополнительные вопросы
1. Влияет ли размер value type на то, где его разместят?
1. Влияет ли размер value type на то, где его разместят?
Если тип значения хранится в свойстве класса, он лежит внутри экземпляра этого класса. Экземпляр размещается в куче, поэтому и значение оказывается там же.
// Value Type
struct Point {
var x = 1
}
// Reference Type
class Holder {
// Структура живет в куче
var point = Point()
}Если замыкание захватывает тип значения и это замыкание вызывают после выхода из функции, значение уже нельзя держать на стеке. Swift сохраняет его в куче, и замыкание продолжает работать с ним.
// Value Type
struct Progress {
let step = 1
}
// Reference Type
var getNextStepClosure: ((Int) -> Int)!
func initProgress() {
let progress = Progress()
getNextStepClosure = { value in
// Замыкание извне захватывает структуру и держит её в куче.
return value + progress.step
}
}
initProgress() // Функция завершилась
// Замыкание и Progress продолжают жить
print(getNextStepClosure(1)) // 2
print(getNextStepClosure(2)) // 3Если тип значения кладут в переменную типа протокола, Swift упаковывает его в экзистенциальный контейнер.
Экзистенциальный контейнер это некая упаковка для протокола. Компилятор не знает конкретный тип, который будет подписан под этот протокол, а значит, и не знает его размер. Поэтому для любого значения резервируется одинаковый объём памяти.
Если значению хватает зарезервированного места, оно лежит прямо в контейнере. Если не влезает, то компилятор размещает само значение в куче, а в контейнер кладёт ссылку на него.
protocol Shape {}
struct Polygon: Shape {
var a = 1
var b = 2
var c = 3
var d = 4
}
// Polygon не влезает в контейнер, поэтому само значение лежит в куче
let shape: any Shape = Polygon()1. Размер влияет на размещение, когда тип значения хранят как протокол. Если значение не влезает в экзистенциальный контейнер, само значение оказывается в куче. Обычную структуру в переменной компилятор на кучу из-за размера не переносит: она остаётся на стеке.