Где в Swift применяется Copy-on-write?

Ответ

Copy-on-write (CoW) — это оптимизация, применяемая к стандартным типам-значениям в Swift (Array, Dictionary, Set, String). Её цель — избежать избыточного копирования данных.

Как это работает: При присваивании или передаче значения создаётся новая ссылка на общее хранилище данных. Фактическое копирование (дублирование буфера в памяти) происходит только в момент первой модификации одной из копий.

Пример:

var array1 = [1, 2, 3]
var array2 = array1 // Нет реального копирования. Оба массива ссылаются на один буфер.

// Проверяем, что хранилище общее (в реальности это внутренняя деталь реализации)
print(array1[0]) // 1

array2.append(4) // Происходит CoW! Для array2 создаётся отдельная копия буфера.
print(array1) // [1, 2, 3] — array1 не изменился
print(array2) // [1, 2, 3, 4]

Почему это важно:

  • Эффективность: Передача больших массивов как параметров функции становится дешёвой операцией.
  • Семантика значений: Сохраняется ожидаемое поведение типа-значения — каждая переменная ведёт себя как независимая копия после модификации.

Где ещё используется?

  • В SwiftUI для оптимизации работы с property wrappers, такими как @State.
  • Вы можете реализовать CoW для своих собственных структур, используя классы для внутреннего хранения данных и проверку ссылок (isKnownUniquelyReferenced).

Ответ 18+ 🔞

А, слушай, про эту вашу CoW, Copy-on-write, блядь! Ну, оптимизация такая, хитрая жопа, чтобы не копировать всё подряд, как дурак.

Вот представь: у тебя есть массив, здоровенный, на овердохуища элементов. И ты его, блядь, в функцию передаёшь или просто в другую переменную пихаешь. По логике-то, это же тип-значение, ёпта! Должно скопироваться всё, весь этот пиздец, новый кусок памяти занять. А это, блядь, дорого! Компьютер будет ебаться как проклятый.

Так вот, Swift — не лох, блядь. Он делает так: когда ты пишешь var array2 = array1, он тебе не копирует нихуя! Он просто даёт вторую ссылку на то же самое, ёбаное, хранилище в памяти. Обе переменные смотрят в одну кучу, как два мудака в одну бутылку.

И всё бы хорошо, но если один начнёт эту кучу менять, а второй от этого страдать — это ж пиздец, нарушение святых принципов! Тип-значение должен быть независимым, блядь!

Поэтому CoW — это как хитрая ловушка. Пока все только читают — живём дружно, ссылаемся на одно и то же. Но стоит кому-то сделать запись, как система его, сука, ловит за руку: «Ага, мудила, решил испортить общее? Получай свою личную, блядь, копию!». И только тогда, в этот самый момент, происходит реальное копирование данных. Умно, да? Волнение ебать!

Вот, смотри на примере, тут всё понятно:

var array1 = [1, 2, 3]
var array2 = array1 // Тишина, блядь. Ничего не копируется. Просто два ярлыка на одну папку.

print(array1[0]) // Читаем. Всё спокойно.

array2.append(4) // ОПА-ЧКИ! Запись! Ёперный театр, триггер сработал!
// Тут Swift хватается за голову: «array2, ты что творишь, они же общее хранилище используют!».
// И БАЦ — создаёт для array2 его собственную, отдельную копию данных в памяти.
// И только потом добавляет туда четвёрку.

print(array1) // [1, 2, 3] — а этот, блядь, ничего и не почувствовал, живёт себе спокойно.
print(array2) // [1, 2, 3, 4] — а у этого теперь своя квартира, делает что хочет.

И зачем этот цирк, спросишь? Да затем, чувак, чтобы и волки (производительность) были сыты, и овцы (семантика значений) целы! Передавать тяжёлые структуры — дёшево, а ведут себя они всё равно как честные, независимые копии. Красота, блядь!

Это где ещё встрять может? Да везде, блядь! Вся эта ваша модная SwiftUI на этом стоит, там у них @State и прочие обёртки так же выёбываются. Да и ты сам, если не ленивая жопа, можешь для своих структур такую же механику прикрутить, используя isKnownUniquelyReferenced. Но это уже, как говорится, высший пилотаж, в рот меня чих-пых.