protocol Observer {
associatedtype T
func notify(_ value: T)
}
Это говорит о том, что данный наблюдатель может обрабатывать один конкретный тип (T
), который выбирает наблюдатель.
protocol Observable {
var observers: [Observer] { get set }
func registerObserver(_ observer: Observer)
func unregisterObserver(_ observer: Observer)
}
Это недопустимо, поскольку система не может узнать, что T
вы хотите для этих наблюдателей.Каждый наблюдатель может обращаться только с одним T
.
protocol Observer {
func notify<T>(_ value: T)
}
Это в принципе бессмысленно.Он говорит, что notify может быть вызван с любым типом вообще.Если это то, что вы имеете в виду, вы хотите сказать:
protocol Observer {
func notify(_ value: Any)
}
Но это означает, что каждый наблюдатель должен иметь дело с Any
, что нехорошо.Причина, по которой это работает, в том, что вы выбрали print
в качестве теста.print
может справиться Any
.Когда вы хотите протестировать такие вещи, вам нужно попробовать что-то вроде того, что вы действительно хотите сделать в своей программе.Печать работает для всех видов вещей, которые бесполезны для каких-либо других целей.
Основная проблема заключается в том, что Observer
не должен быть протоколом.Это должна быть функция.Например:
typealias Observer<T> = (T) -> Void
protocol Observable {
associatedtype T
var observers: [Observer<T>] { get set }
func registerObserver(_ observer: Observer<T>)
func unregisterObserver(_ observer: Observer<T>)
}
Проблема этого подхода в том, что нет способа реализовать unregisterObserver
.Мне также не ясно, как вы реализовали unregisterObserver
в своем коде.На самом деле это не выглядит возможным.
Вот один очень простой способ построения наблюдаемой:
typealias Observer<T> = (T) -> ()
struct Subscription {
let cancel: () -> Void
}
final class Observable<T> {
private var observations: [UUID: Observer<T>] = [:]
func subscribe(observer: @escaping Observer<T>) -> Subscription {
let uuid = UUID()
observations[uuid] = observer
return Subscription(cancel: { [weak self] in self?.observations[uuid] = nil })
}
}
(см. https://stackoverflow.com/a/55389143/97337, откуда это.)
Для более полностью проработанной версии, которая очень проста, см. Observable .Для несколько более сложной версии, которая немного причудлива, см. Stream .Для более мощной и менее причудливой версии см. Свойства .Для очень мощной версии, которая устанавливает целый способ программирования, см. RxSwift .