Would it make sense to pass the observer as a parameter in the callback closure? Something like:
public func subscribe(with observer: ObserverType, callback: @escaping (ObserverType, T) -> T) -> Signals.SignalSubscription<ObserverType, T>
This will allow to convert this:
signal.subscribe(with: self) { [weak self] (newValue) in
guard let weakSelf = self else { return } // Boilerplate + easy to forget
weakSelf.property = newValue
}
Or this:
signal.subscribe(with: self) { (newValue) in
self.property = newValue // Retain cycle!!!!
}
Into this:
signal.subscribe(with: self) { (observer, newValue) in
observer.property = newValue
}