К каким типам в Swift применяется механизм copy-on-write (COW)?

«К каким типам в Swift применяется механизм copy-on-write (COW)?» — вопрос из категории Swift Core, который задают на 23% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Copy-on-write (COW) применяется к типам-значениям (value types), копирование которых было бы дорогостоящим. Механизм откладывает реальное копирование данных до момента модификации.

Стандартные типы Swift с COW:

  1. Array, Dictionary, Set — все коллекции стандартной библиотеки
  2. String и его представления (Substring, String.UTF8View)

Пример работы COW:

var originalArray = [1, 2, 3, 4, 5]
var copiedArray = originalArray // Нет реального копирования, общий буфер

print(originalArray[0]) // 1
print(copiedArray[0])   // 1

// Модификация вызывает реальное копирование:
copiedArray.append(6)

print(originalArray) // [1, 2, 3, 4, 5]
print(copiedArray)   // [1, 2, 3, 4, 5, 6] // Теперь разные буферы

Реализация COW для пользовательских типов:

final class Ref<T> {
    var value: T
    init(_ value: T) { self.value = value }
}

struct COWBox<T> {
    private var ref: Ref<T>

    init(_ value: T) {
        ref = Ref(value)
    }

    var value: T {
        get { ref.value }
        set {
            // Копируем только при модификации и множественных ссылках
            if !isKnownUniquelyReferenced(&ref) {
                ref = Ref(newValue)
            } else {
                ref.value = newValue
            }
        }
    }
}

// Использование:
var box1 = COWBox([1, 2, 3])
var box2 = box1 // Общий Ref
box2.value.append(4) // Создается новый Ref только здесь

Ключевые моменты:

  • isKnownUniquelyReferenced(&object) проверяет, единственная ли ссылка на объект
  • COW оптимизирует память и производительность для часто копируемых структур
  • Важно для больших структур данных, передаваемых по значению