Let say that instead of BoxDelegate you have a class, and let's call it Listener :public typealias ValueChanged <T> = (T) -> Voidpublic class Listener<T> { var valueChanged: ValueChanged<T> public init(_ valueChanged: @escaping ValueChanged<T>) { self.valueChanged = valueChanged }}Box 现在可以这样写:class Box<T> { // the listener needs to be weak in order to be deallocated when the that is // observing the changes is deallocated weak private(set) var listener: Listener<T>? init(_ listener: Listener<T>) { self.listener = listener }}您现在可以为需要观察其状态的属性创建一个包装类:and you can now have a wrapper class for the properties whose state you need to observe:class Observed<T> { var listeners: [Box<T>] = [] private let queue: DispatchQueue = .main var value: T { didSet { notifyListeners() } } func notifyListeners() { notifyListeners(value) } func notifyListeners(_ value: T) { queue.async { [weak self] in self?.listeners.forEach { (box) in box.listener?.valueChanged(value) } } } func bind(_ listener: Listener<T>) { listeners.append(Box(listener)) } func bind(_ listener: @escaping ValueChanged<T>) -> Listener<T> { let listener = Listener(listener) listeners.append(Box(listener)) return listener } init(_ value: T) { self.value = value }}甚至还有一个属性包装器:and even have a property wrapper:@propertyWrapperstruct Bind<T> { let observable: Observed<T> init(wrappedValue: T) { observable = Observed(wrappedValue) } var wrappedValue: T { get { observable.value } set { observable.value = newValue } } var projectedValue: Observed<T> { observable }}用法:var text = ""class ViewModel { @Bind var isOn: Bool = false}let viewModel = ViewModel()let bond = viewModel.$isOn.bind { isOn in if isOn { text = "on" } else { text = "off" }}viewModel.isOn = trueRunLoop.main.run(until: Date().advanced(by: 0.1))textviewModel.isOn = falseRunLoop.main.run(until: Date().advanced(by: 0.1))text 这篇关于为类创建通用委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-14 04:59