Target: AnyObject, Value2>(keyPath keyPath1: KeyPath<CountViewModel, Value1>, bindTo target: Target, _ keyPath2: ReferenceWritableKeyPath<Target, Value2>) { let name: Notification.Name switch keyPath1 { case \CountViewModel.count: name = Names.countChanged ... // other cases } let handler: () -> () = { [weak self, weak target] in guard let me = self, let target = target, let value = me[keyPath: keyPath1] as? Value2 else { return } target[keyPath: keyPath2] = value } handler() observers.append(center.addObserver(forName: name, object: nil, queue: .main) { _ in handler() }) } }