Что такое паттерн Singleton и как его реализовать в Swift?

«Что такое паттерн Singleton и как его реализовать в Swift?» — вопрос из категории Паттерны, который задают на 24% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Singleton — порождающий паттерн, гарантирующий существование только одного экземпляра класса и предоставляющий глобальную точку доступа к нему.

Классическая реализация в Swift:

final class AppSettings {
    // 1. Единственный общий экземпляр
    static let shared = AppSettings()

    // 2. Приватный инициализатор предотвращает создание других экземпляров
    private init() { 
        // Инициализация
    }

    // 3. Данные/состояние синглтона
    var currentTheme: Theme = .light
    var apiBaseURL: String = "https://api.example.com"
}

// Использование:
AppSettings.shared.currentTheme = .dark
let url = AppSettings.shared.apiBaseURL

Ключевые характеристики:

  • final класс — предотвращает наследование и возможное нарушение паттерна.
  • Потокобезопасность — в Swift static let инициализируется лениво и атомарно.
  • Глобальный доступ — через ClassName.shared.

Когда использовать:

  • Менеджеры ресурсов (NetworkManager, DatabaseManager).
  • Логгеры, аналитика.
  • Конфигурация приложения.

Проблемы и альтернативы:

  • Тестирование — синглтон усложняет unit-тесты (используйте Dependency Injection).
  • Скрытые зависимости — код становится связанным (tight coupling).
  • Альтернативы — передача зависимостей через инициализатор, использование Service Locator.

Потокобезопасная модификация:

class ThreadSafeSingleton {
    static let shared = ThreadSafeSingleton()
    private init() {}

    private let queue = DispatchQueue(label: "com.singleton.queue", attributes: .concurrent)
    private var _value = 0

    var value: Int {
        get {
            return queue.sync { _value }
        }
        set {
            queue.async(flags: .barrier) { self._value = newValue }
        }
    }
}