Где в памяти размещаются глобальные и статические переменные в iOS?

Ответ

Глобальные и статические переменные размещаются в сегменте данных (data segment) исполняемого файла, который загружается в память при запуске приложения. Их время жизни равно времени жизни всей программы.

Детали размещения:

Тип переменной Сегмент Инициализация
Инициализированные глобальные/статические (var x = 5) .data (data section) При загрузке программы
Неинициализированные или равные нулю (var y: Int?) .bss (Block Started by Symbol) Заполняются нулями при загрузке

Примеры в коде:

// Инициализированная глобальная переменная -> .data segment
let appVersion: String = "1.0"

// Неинициализированная глобальная переменная -> .bss segment
var userSessionCount: Int // Или `var userSessionCount: Int? = nil`

// Статическая переменная внутри типа/функции -> также .data/.bss
class NetworkManager {
    static let shared = NetworkManager() // Объект в куче, ссылка в .data
    static var requestTimeout: TimeInterval = 30.0 // Значение в .data
}

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

  • Для ссылочных типов (экземпляров классов): Сам объект создается в куче (heap), а сама ссылка (указатель) хранится в data segment.
  • Потокобезопасность: Доступ к глобальным переменным из нескольких потоков требует синхронизации (например, с помощью DispatchQueue, actors или замков).
  • Архитектурные соображения: Чрезмерное использование глобального состояния усложняет тестирование, понимание потока данных и может привести к скрытым зависимостям. Предпочтительны инъекция зависимостей и четко ограниченные контейнеры состояния.

Ответ 18+ 🔞

Да ты послушай, как эти глобальные и статические переменные устроены, блядь! Они же, сука, не где попало болтаются, а сразу в сегмент данных (data segment) прописываются, в самую программу. Загрузили приложение — и они уже тут как тут, до самого конца, пока ты не вырубишь всё нахуй. Живут дольше, чем некоторые отношения, ей-богу.

А вот куда конкретно их пихают, смотри:

Тип переменной Сегмент Инициализация
Инициализированные глобальные/статические (var x = 5) .data (data section) Как программу запустили — всё уже готово
Неинициализированные или равные нулю (var y: Int?) .bss (Block Started by Symbol) При загрузке их просто нулями забивают, вот и вся магия

Чтоб совсем понятно было, на коде покажу:

// Инициализированная глобальная переменная -> летит прямиком в .data segment
let appVersion: String = "1.0"

// Неинициализированная глобальная переменная -> отправляется в .bss segment, в царство нулей
var userSessionCount: Int // Или `var userSessionCount: Int? = nil`

// Статическая переменная внутри класса/функции — та же история, .data/.bss
class NetworkManager {
    static let shared = NetworkManager() // Сам объект — в куче, а ссылка на него — в .data
    static var requestTimeout: TimeInterval = 30.0 // А это значение уже прямо в .data
}

А теперь главное, что надо уяснить, а то накосячишь:

  • Ссылочные типы (объекты классов): Сам объект, понятное дело, в куче (heap) сидит, а вот ссылка (этот самый указатель) — она уже в data segment прописана, как паспортные данные.
  • Потокобезопасность, ёпта: Если с этими глобальными переменными из нескольких потоков работать начнёшь без спросу — будет пиздец и race condition. Так что либо DispatchQueue, либо actors, либо замки какие — без этого никуда.
  • Архитектурные соображения, блядь: Если наглухо закидаешь проект глобальным состоянием, то потом сам в нём не разберёшься, тестировать невозможно будет, а зависимости будут как паутина. Охуенно же? Лучше инъекцию зависимостей использовать и контейнеры состояния построже делать. А то получится хитрая жопа, а не архитектура.