我目前正在回去清理一些(非常)旧的代码,作为构建一些新功能的一部分。
我试图修复的反模式之一是我的 View Controller 有点太接近上帝类了,试图在它自己内部做所有事情而不是让较小的 subview 做一些工作.我正在尝试移动事物,以便状态存在于 VC 中,它传递到 subview 中以进行操作。非常类似于 React 如何让容器将 props 传递给组件。
我遇到的问题是,当状态被传递到 Root View Controller 时,这些 subview 不一定加载并准备好接受它们的初始状态。
一个真正简化的版本是:
class DemoVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
subView?.propertyClass = self.propertyClass
}
@IBOutlet weak var subView: UIView!
var propertyClass:PropertyClass!{
didSet{
subView?.propertyClass = propertyClass
//More side effects
}
}
}
请注意,我现在在两个地方传播数据:一次在 setter 中(很好),但我还必须在 View 加载时传递它。对于一个条目,这不一定那么糟糕。我需要跟踪最多四个实际状态,而且我还远远没有完成。 viewDidLoad 方法包含 subview1.property = self.property
的二十种不同变体的想法——具有不同的属性,不同的 subview ,经常在多个 subview 上重复相同的属性——对我来说似乎有点过分.我可以在这里使用更好的设计模式,还是我坚持使用它?
最佳答案
您可以使用简单的 protocol
和 subviews
属性来减少代码:
protocol PropertyHandler {
func setProperties(_ propertyClass: Any) // Could be the type you need instead of `Any`
}
这将强制您的自定义 View 实现该功能。
extension MyCustomView: PropertyHandler {
func setProperties(_ propertyClass: Any) {
// Set properties
}
}
然后你可以在所有符合协议(protocol)
的 subview 上应用它:
var propertyClass: PropertyClass! {
didSet {
for subview in view.subviews {
guard let propertyHandler = subview as? PropertyHandler else { continue }
propertyHandler.setProperties(propertyClass)
}
}
}
更新:
您还可以使用generic
的强大功能:
protocol PropertyHandler {
func setProperties<T>(_ propertyClass: T)
}
关于ios - 我如何消除 setter 对 View 的副作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58867632/