TGViewer
Мобильный трудоголик Мобильный трудоголик @hardworkerit · 1.65K subscribers
Post #213 1.32K
🔢 Массивы в Swift: больше чем кажется на первый взгляд.

Друзья, сегодня поговорим о массивах в Swift. Казалось бы, самой базовой структуре данных, но с интересными особенностями под капотом.


Value type но со своими хитростями.

Массивы - это структуры (value types), но данные хранятся в куче. При присваивании в переменную создается новая структура, но буфер с данными остается общим до момента модификации (Copy-on-Write):


var array1 = [1, 2, 3]
var array2 = array1 // Пока нет копирования данных
array1.append(4) // Только теперь данные копируются



Работа с ссылочными типами.

С классами нужно быть аккуратнее:


class User {
var name: String

init(name: String) {
self.name = name
}
}

let users1 = [User(name: "Artem"), User(name: "Dima")]
let users2 = users1

users1[0].name = "Egor" // Изменение затронет оба массива
print(users2[0].name) // Egor


Для глубокого копирования нужно реализовать протокол NSCopying. Без него при копировании массива с классами создаются только новые ссылки на те же объекты в памяти. NSCopying позволяет создать настоящие копии каждого объекта.


Производительность операций с массивами.

На практике важно понимать сложность основных операций с массивами, чтобы выбирать оптимальные подходы:

🔹 append() - в среднем O(1), но при расширении буфера происходит копирование всех элементов.
🔹 removeLast() - O(1), так как не требует сдвига элементов.
🔹 remove(at:) - O(n) из-за необходимости сдвигать все последующие элементы.
🔹 insert(_:at:) - O(n) по той же причине, что и remove(at:).


Эффективная работа с частями массива (ArraySlice).

ArraySlice работает как указатель на определенный диапазон элементов в оригинальном массиве. Это особенно полезно при работе с большими массивами:


let largeArray = Array(0..<1000000) // Большой массив
let slice = largeArray[1000..<2000] // Не копирует миллион элементов!

// Используем срез как обычный массив
for element in slice {
print(element) // Работает с элементами 1000-1999
}


Но важно помнить: ArraySlice сохраняет сильную ссылку на весь исходный массив. Это может привести к неожиданному потреблению памяти. Вот решение:


let largeArray = Array(0..<1000000) // Большой массив
let slice = largeArray[1000..<2000] // Не копирует миллион элементов!

// Создаем новый массив если нужна независимая копия
let independentCopy = Array(slice) // Теперь largeArray можно освободить



Массивы под капотом.

Swift использует разные буферы в зависимости от контекста:

🔹 _ContiguousArrayBuffer - для Swift-типов.
🔹 _ArrayBuffer - при работе с Objective-C.


🔗 Ссылка на подробную статью


💡 Вывод:

Массивы в Swift - это не просто списки значений. Понимание их устройства помогает писать более эффективный код и избегать неочевидных проблем.


➡️ Подписаться на канал
Мобильный трудоголик
  • 👍 24
  • ❤ 18
  • 🔥 10
  • 🙏 3
  • 🤝 1
More from @hardworkerit
  1. Oct 6, 2026🔢 Swift 6.4: новая диагностика ретейн циклов. В Swift 6.4 появилась новая диагностика, ко…
  2. Oct 4, 2026🔢 SwiftUI: определение угла раскрытия iPhone Duo. В iOS 27.1 появился модификатор .onHing…
  3. Oct 2, 2026👣 Архитекторы, тестировщики и кодеры. Создаем мультиагентную команду Разработка с ИИ-аген…
  4. Oct 1, 2026🔢 Работа с Picture-in-Picture в iOS. Picture-in-Picture - системная функция iOS, которая…
  5. Sep 29, 2026🔢 Управление тулбарами на iPhone Duo. На iPhone Duo элементы управления навигацией, дейст…
  6. Sep 27, 2026🔢 Новые возможности Hashable в Swift 6.4 В Swift 6.4 добавили Hashable для нескольких тип…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →