Здравствуйте, друзья! Сегодня разберем одну из самых интересных тем в 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 - это мощный механизм, но не бесплатный. Понимание его работы помогает писать более эффективный код.
➡️ Подписаться на канал
Мобильный трудоголик
