Ответ
Глобальные и статические переменные размещаются в сегменте данных (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, либо замки какие — без этого никуда. - Архитектурные соображения, блядь: Если наглухо закидаешь проект глобальным состоянием, то потом сам в нём не разберёшься, тестировать невозможно будет, а зависимости будут как паутина. Охуенно же? Лучше инъекцию зависимостей использовать и контейнеры состояния построже делать. А то получится хитрая жопа, а не архитектура.