Observer (Наблюдатель) — это поведенческий паттерн проектирования, который создает механизм подписки для уведомления множества объектов об изменениях состояния наблюдаемого объекта. В iOS он реализован несколькими способами.
// Отправка уведомления
NotificationCenter.default.post(
name: Notification.Name("DataUpdated"),
object: nil,
userInfo: ["data": newData]
)
// Подписка на уведомление
NotificationCenter.default.addObserver(
self,
selector: #selector(handleDataUpdate(_:)),
name: Notification.Name("DataUpdated"),
object: nil
)
// Обработчик
@objc func handleDataUpdate(_ notification: Notification) {
guard let data = notification.userInfo?["data"] as? DataType else { return }
updateUI(with: data)
}
// Отмена подписки
deinit {
NotificationCenter.default.removeObserver(self)
}
class ObservedObject: NSObject {
@objc dynamic var value: String = "" // Помечаем как динамическое свойство
}
let object = ObservedObject()
var observation: NSKeyValueObservation?
// Настройка наблюдения
observation = object.observe(\.value, options: [.new, .old]) { object, change in
print("Value changed from \(change.oldValue ?? "") to \(change.newValue ?? "")")
}
// Изменение значения
object.value = "New Value" // Вызовет обработчик
// Отмена наблюдения
observation?.invalidate()
import Combine
class DataModel {
@Published var data: String = "" // Наблюдаемое свойство
}
let model = DataModel()
var cancellables = Set<AnyCancellable>()
// Подписка
model.$data
.sink { newValue in
print("Data updated to \(newValue)")
}
.store(in: &cancellables)
// Изменение значения
model.data = "Updated Data" // Вызовет подписчика
class UserSettings: ObservableObject {
@Published var isLoggedIn = false
}
struct ContentView: View {
@ObservedObject var settings = UserSettings()
var body: some View {
Toggle("Logged In", isOn: $settings.isLoggedIn)
}
}
Способ | Плюсы | Минусы |
---|---|---|
NotificationCenter | Простота, широковещательность | Нетипобезопасность, строковые ключи |
KVO | Автоматическое наблюдение | Сложный API, требует NSObject |
Combine | Типобезопасность, мощный API | Только iOS 13+, кривая обучения |
SwiftUI Binding | Интеграция с UI | Только для SwiftUI |
class UserViewModel {
@Published var username: String = ""
@Published var isLoading = false
private var cancellables = Set<AnyCancellable>()
func fetchUser() {
isLoading = true
NetworkService.fetchUser()
.receive(on: DispatchQueue.main)
.sink(
receiveCompletion: { [weak self] _ in
self?.isLoading = false
},
receiveValue: { [weak self] user in
self?.username = user.name
}
)
.store(in: &cancellables)
}
}
Observer — мощный паттерн для реактивного программирования в iOS. Выбор реализации зависит от:
Современные приложения все чаще используют Combine и SwiftUI-механизмы, но NotificationCenter и KVO остаются актуальными для legacy-кода. Главное — соблюдать правила отмены подписок и учитывать потокобезопасность.
Для новых проектов рекомендуется изучать Combine — это будущее реактивного программирования в экосистеме Apple.