Ответ
В современных iOS-фреймворках Singleton заменяют следующими подходами:
1. Dependency Injection (DI) — явная передача зависимостей через инициализатор или свойство. Это улучшает тестируемость и читаемость кода.
protocol ServiceProtocol {
func fetchData() -> Data
}
class ViewModel {
private let service: ServiceProtocol
init(service: ServiceProtocol) {
self.service = service
}
func load() -> Data {
return service.fetchData()
}
}
2. SwiftUI Environment — использование @EnvironmentObject и @Environment для передачи зависимостей по иерархии представлений.
3. Контейнеры зависимостей — библиотеки типа Swinject или Factory для централизованного управления зависимостями.
4. Акторы (Actors) — для потокобезопасного доступа к общим ресурсам вместо глобального состояния.
@MainActor
class GlobalService {
static let shared = GlobalService()
private init() {}
func update() async { /* ... */ }
}
Почему DI предпочтительнее Singleton?
- Тестируемость: Легко подменить реальную зависимость моком.
- Гибкость: Зависимости можно менять без изменения класса.
- Ясность: Все зависимости явно объявлены в интерфейсе класса.