Ответ
Copy-on-write (CoW) — это оптимизация, при которой копирование данных откладывается до момента фактической модификации. В Swift строки (тип String) реализуют этот механизм.
Как это работает:
- При присваивании строки другой переменной создается только новая ссылка на те же данные
- Фактическое копирование буфера памяти происходит только при попытке изменить одну из копий
Пример:
var original = "Hello, World!"
var copy = original // Нет копирования, обе переменные ссылаются на один буфер
print(original == copy) // true
// Проверим, что это одна и та же память (условно)
print(CFGetRetainCount(original as CFString)) // Увеличится счетчик ссылок
copy.append("!") // ТЕПЕРЬ происходит копирование!
// original и copy теперь имеют разные буферы в памяти
print(original) // "Hello, World!"
print(copy) // "Hello, World!!"
Реализация CoW для пользовательских структур:
struct MyCoWStruct {
private class Ref<T> {
var value: T
init(_ value: T) { self.value = value }
}
private var ref: Ref<[Int]>
init(values: [Int]) {
ref = Ref(values)
}
var values: [Int] {
get { return ref.value }
set {
// Проверяем, единственная ли это ссылка
if !isKnownUniquelyReferenced(&ref) {
ref = Ref(newValue) // Копируем при модификации
return
}
ref.value = newValue
}
}
}
var a = MyCoWStruct(values: [1, 2, 3])
var b = a // Нет копирования
b.values.append(4) // Происходит копирование, так как b изменяется
Важные особенности:
- CoW работает только для типов-значений (struct, enum)
- Компилятор Swift автоматически применяет CoW для стандартных коллекций (Array, Dictionary, Set) и строк
- Для кастомных структур нужно реализовывать CoW вручную
- Механизм не гарантирован для очень маленьких структур, где копирование дешевле проверки уникальности ссылки
Преимущества:
- Экономия памяти при частом копировании
- Быстрое присваивание без накладных расходов
- Прозрачность для разработчика (работает автоматически)