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

Copy-on-Write в Swift: как массивы экономят память

Всем привет! Наткнулся на статью, где автор подробно разбирает механизм Copy-on-Write (COW) в Swift. Это та самая технология, благодаря которой массивы, строки и словари ведут себя как типы значений, но при этом не создают полные копии больших объемов данных при каждом присваивании.

Что такое COW простыми словами:


Когда вы присваиваете массив другой переменной, Swift не создает полноценную копию. Обе переменные ссылаются на одни и те же данные в памяти. Только когда одна из них начинает изменяться, Swift создает уникальную копию для нее. Отсюда и название - копирование при записи.

Это позволяет Swift сохранять семантику значений (изменение одной копии не влияет на другую) без дорогостоящего копирования больших объемов данных.

Как это работает под капотом:


Тип-значение (например ваш массив) хранит ссылку на объект-хранилище (класс). При присваивании копируется ссылка, а не само хранилище. При попытке изменения вызывается метод isKnownUniquelyReferenced(_:), который проверяет, есть ли у хранилища другие ссылки. Если есть - создается новое хранилище с копией данных, и только потом происходит изменение.

Проверить уникальность можно и в своем коде, если вы пишете кастомную COW-структуру.

Как реализовать свой COW-контейнер:


Автор приводит пример SharedBuffer:

  • Публичная структура-обертка.

  • Внутренний класс Storage, хранящий массив элементов.

  • Метод ensureUniqueStorage(), который копирует хранилище, если на него есть другие ссылки.

  • Все мутирующие методы сначала вызывают ensureUniqueStorage()


Простой, но эффективный паттерн.

Распространенные заблуждения:


  • «Структуры автоматически используют COW». Нет. COW - это стратегия реализации конкретных типов (Array, String, Dictionary). Ваши структуры по умолчанию копируются целиком.

  • «COW рекурсивно копирует все вложенные объекты». Нет. Копируется только само хранилище контейнера. Если внутри лежат ссылочные типы, их изменение не триггерит COW.

Итоговая мысль:


COW - один из тех механизмов Swift, о котором редко задумываешься, пока он работает. Но когда вы начинаете проектировать свои типы, управляющие большими объемами данных, понимание COW становится критическим. Особенно если вы пишете библиотеку или работаете с тяжелыми коллекциями. Стандартная семантика значений с прямым копированием просто убьет производительность. А собственный COW-контейнер решит проблему элегантно.

Что мне нравится в подходе автора - он не просто объясняет механизм, а показывает работающий код и предупреждает о подводных камнях (например что isKnownUniquelyReferenced не работает с Objective-C-объектами и требует дополнительных проверок для классовых протоколов).

Вывод:


Copy-on-Write - один из ключевых механизмов, позволяющих Swift сочетать производительность и безопасность. Понимание того, как он работает, дает вам инструмент для проектирования эффективных структур данных и помогает писать более производительный код.
06.05.2026 50 404