← Назад к вопросам

Что будет, если скопировать массив с данными?

1.3 Junior🔥 222 комментариев
#Управление памятью

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Копирование массива данных в iOS (Swift)

Когда мы говорим о копировании массива в Swift, необходимо понимать, что поведение зависит от типа элементов массива и способа копирования. Swift использует концепцию Copy-on-Write (CoW) для оптимизации работы с коллекциями и структурами.

Копирование массива значений (например, структур)

Если массив содержит структуры (structs), которые являются типами-значениями (value types), при копировании массив создаёт физическую копию данных. Однако благодаря механизму Copy-on-Write реальное копирование происходит только при необходимости — когда один из массивов изменяется.

Рассмотрим пример:

struct Person {
    var name: String
    var age: Int
}

var originalArray = [Person(name: "Alice", age: 25), Person(name: "Bob", age: 30)]
var copiedArray = originalArray // На этом этапе обе переменные ссылаются на одни данные

print(originalArray[0].name) // Alice
print(copiedArray[0].name)   // Alice

// Модификация одного массива вызывает реальное копирование
copiedArray[0].name = "Carol"
print(originalArray[0].name) // Alice (не изменилось!)
print(copiedArray[0].name)   // Carol

Key points:

  • До модификации массивы ссылаются на одни данные (оптимизация памяти)
  • При изменении любого массива происходит реальное копирование
  • После копирования массивы становятся полностью независимыми

Копирование массива объектов (классы)

Если массив содержит объекты классов (classes), которые являются типами-ссылочными (reference types), копирование массива создаёт новую коллекцию, но элементы внутри остаются теми же объектами (копируются только ссылки).

class PersonClass {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

let person1 = PersonClass(name: "Alice", age: 25)
let person2 = PersonClass(name: "Bob", age: 30)

var originalArray = [person1, person2]
var copiedArray = originalArray // Копируется массив ссылок, сами объекты не копируются

copiedArray[0].name = "Carol"
print(originalArray[0].name) // Carol (изменилось!)
print(copiedArray[0].name)   // Carol

Key points:

  • Копируется только массив ссылок на объекты
  • Самые объекты не дублируются
  • Изменение объекта через любой массив влияет на "оригинал"

Явное глубокое копирование (Deep Copy)

Для создания полностью независимой копии массива объектов необходимо выполнить глубокое копирование (deep copy):

// Если класс поддерживает протокол NSCopying
class PersonClass: NSCopying {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    func copy(with zone: NSZone? = nil) -> Any {
        return PersonClass(name: self.name, age: self.age)
    }
}

let person1 = PersonClass(name: "Alice", age: 25)
let person2 = PersonClass(name: "Bob", age: 30)

var originalArray = [person1, person2]
var deepCopiedArray = originalArray.map { $0.copy() as! PersonClass }

deepCopiedArray[0].name = "Carol"
print(originalArray[0].name) // Alice (не изменилось!)
print(deepCopiedArray[0].name) // Carol

Практические рекомендации

  • Для массивов структур копирование безопасно и эффективно благодаря CoW
  • Для массивов объектов учитывайте, что копируются только ссылки
  • Для создания полностью независимых копий объектов реализуйте механизм глубокого копирования
  • При работе с большими массивами учитывайте затраты памяти при реальном копировании

В заключение: поведение при копировании массива в Swift зависит от типа элементов и контекста использования. Правильное понимание этих механизмов помогает избежать неожиданного поведения и оптимизировать использование памяти.

Что будет, если скопировать массив с данными? | PrepBro