В чем разница между safe (безопасным) и unsafe (небезопасным) кодом в Swift?

«В чем разница между safe (безопасным) и unsafe (небезопасным) кодом в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Различие касается гарантий безопасности памяти и типов, предоставляемых языком.

Safe (Безопасный) код

  • Работает с высокоуровневыми типами Swift (Array, String, структуры).
  • Память управляется автоматически (ARC).
  • Гарантирует безопасность: проверка границ массивов, инициализация переменных, отсутствие висячих указателей.
  • Компилятор предотвращает множество распространенных ошибок.
// Safe пример
var safeArray = [1, 2, 3]
safeArray.append(4) // Безопасное добавление
let value = safeArray[0] // Проверка индекса во время выполнения

Unsafe (Небезопасный) код

  • Использует указатели (UnsafePointer<T>, UnsafeMutablePointer<T>, UnsafeRawBufferPointer).
  • Требует ручного контроля за временем жизни памяти и корректностью доступа.
  • Может привести к неопределенному поведению (undefined behavior): чтение мусора, повреждение памяти, краши.
  • Используется для взаимодействия с C API или экстремальной оптимизации.
// Unsafe пример
let numbers = [1, 2, 3]
numbers.withUnsafeBufferPointer { bufferPtr in
    // bufferPtr — указатель на память массива
    // Разработчик сам отвечает за корректность работы с ним
    if let baseAddress = bufferPtr.baseAddress {
        print(baseAddress.pointee) // 1
    }
}

Рекомендация: Используйте unsafe API только при крайней необходимости, когда измеренная производительность безопасного кода недостаточна, или для прямого взаимодействия с неуправляемой памятью.