Какие данные хранятся в куче (heap) в iOS/macOS?

Ответ

В куче (heap) хранятся объекты с динамическим временем жизни и ссылочной семантикой, память для которых выделяется явно во время выполнения программы.

Что хранится в куче:

  • Экземпляры классов (reference types) в Swift.
  • Замыкания (closures), захватывающие контекст.
  • Объекты Foundation (NS-объекты, такие как NSArray, NSDictionary, NSString).
  • Буферы для коллекций (например, элементы внутри Array или Dictionary, если они являются ссылочными типами).
  • Любые другие данные, выделенные с помощью malloc или аналогичных функций.

Ключевые особенности кучи:

  • Ручное или автоматическое управление памятью: Требует использования ARC (Automatic Reference Counting) в Swift или ручного retain/release в Objective-C.
  • Разделяемые данные: Несколько переменных могут хранить ссылки на один и тот же объект в куче.
  • Динамический размер: Размер кучи ограничен лишь доступной виртуальной памятью устройства.
  • Более медленный доступ: Выделение и освобождение памяти сложнее, чем в стеке.

Пример:

class Person { // Reference Type
    var name: String
    init(name: String) { self.name = name }
}

// Объект `Person` создаётся и хранится в куче.
// Переменная `person1` в стеке хранит лишь указатель (ссылку) на этот объект.
let person1 = Person(name: "Alice")
let person2 = person1 // Копируется ссылка, а не объект. Обе переменные указывают на один объект в куче.
person2.name = "Bob"
print(person1.name) // "Bob" (изменение через одну ссылку видно через другую)

Ответ 18+ 🔞

Ну ты посмотри, какой цирк с конями развели! Вот есть у нас эта самая куча (heap), куда складывают всякое говно, которое живёт, пока его не прибьют. Там всё на ссылках болтается, и память под это дело выдирают прямо во время работы программы, как последнюю рубашку.

Что там валяется, в этой помойке:

  • Экземпляры классов (reference types) в Swift — ну, классика жанра, блядь.
  • Замыкания (closures), которые утащили с собой пол-окружения, хитрожопые.
  • Объекты из этого старого хлама Foundation — всякие NSArray, NSDictionary, NSString, мать их.
  • Буферы для коллекций — если внутри Array или Dictionary сидят ссылочные типы, то их содержимое тоже тут, в куче, болтается.
  • Ну и вообще любая хуйня, которую выдрали через malloc или что-то похожее — всё сюда, в общую кучу.

А главные фишки этой помойки вот какие:

  • Ручное или автоматическое управление памятью: Тут либо ARC (Automatic Reference Counting) в Swift за тебя всё считает, либо в старом добром Objective-C сам мучайся с retain/release, ебать твою душу.
  • Разделяемые данные: Одна и та же хрень в куче может быть прицеплена к куче переменных. Изменил в одном месте — получил пиздец везде.
  • Динамический размер: Места тут, в теории, овердохуища, пока вся виртуальная память устройства не кончится.
  • Более медленный доступ: Выделить и освободить память тут — это не как в стеке, щёлк и готово. Тут целая операция с поиском места и уборкой мусора, блядь.

Смотри, как это выглядит на практике:

class Person { // Reference Type, ёпта
    var name: String
    init(name: String) { self.name = name }
}

// Объект `Person` создаётся и летит прямиком в кучу.
// Переменная `person1` в стеке — это просто бумажка с адресом, где этот объект лежит.
let person1 = Person(name: "Alice")
let person2 = person1 // Скопировали бумажку с адресом, а не сам объект! Теперь оба знают, где он.
person2.name = "Bob" // Пришли по адресу и нахуйрили новое имя.
print(person1.name) // "Bob" — ага, сука, сюрприз! Изменение через одну бумажку видно через другую, потому что объект-то один!

Вот и весь сказ, блядь. Куча — она такая, хитрая жопа. Удобно, но если не следить, можно так нассывать, что потом все заебешься искать, кто и где что поломал.