Добавить объявление

Existential Container в Swift: что скрывается за протоколами

Здравствуйте, друзья! Сегодня разберем одну из самых интересных тем в Swift: как работают протоколы на низком уровне. Если вы думаете, что протоколы это просто синтаксический сахар, приготовьтесь удивляться!

Что такое Existential Container:


Когда мы объявляем переменную с типом протокола:

var item: MyProtocol = MyStruct()

Компилятор создает специальную сущность: Existential Container. Это коробка, которая хранит:

  • Само значение.

  • Метаданные о типе.

  • Таблицу методов протокола.

Как устроена память:


На 64-битных системах Existential Container занимает 40 байт (5 машинных слов):

  • 24 байта - данные значения.

  • 8 байт - указатель на метаданные типа (VWT).

  • 8 байт - указатель на таблицу методов (PWT).

Inline vs Outline хранение:


Swift умный! Если ваша структура помещается в 24 байта, то данные хранятся прямо в буфере Existential Container (inline):

struct MyStruct: MyProtocol {
let a: Int
let b: Int
let c: Int
}

Если данные больше 24 байт, то создается объект в куче и в буфер контейнера сохраняется только указатель на эту память (outline).

Value Witness Table (VWT):


Это «инструкция по эксплуатации» для типа. VWT содержит функции:

  • initialize - создание значения.

  • copy - копирование.

  • destroy - очистка памяти.


Для тривиальных типов (Int, Double) многие операции пустые заглушки!

Protocol Witness Table (PWT):


Вот где магия! PWT связывает методы протокола с конкретными реализациями:

protocol Drawable {
func draw()
}

struct Circle: Drawable {
func draw() {
}
}

Компилятор создает таблицу, где draw() указывает на реализацию в Circle.

Где находятся VWT и PWT:


Value Witness Table (VWT) и Protocol Witness Table (PWT) хранятся в сегменте данных программы - это статическая память, которая существует на протяжении всего времени жизни приложения.

  • VWT создается для каждого типа на этапе компиляции.

  • PWT создается для каждой пары «тип-протокол» на этапе компиляции.

  • Existential Container содержит только указатели на эти таблицы.

Особенности Existential Container:


  • Existential Container более ресурсоемкий чем Generic.

  • Большие структуры хранятся в куче.

  • Возможно менять типы в runtime.

Вывод:


Existential Container - это мощный механизм, но не бесплатный. Понимание его работы помогает писать более эффективный код.
10.10.2025 66 467