ios - 我如何消除 setter 对 View 的副作用?

标签 ios swift

我目前正在回去清理一些(非常)旧的代码,作为构建一些新功能的一部分。

我试图修复的反模式之一是我的 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 上重复相同的属性——对我来说似乎有点过分.我可以在这里使用更好的设计模式,还是我坚持使用它?

最佳答案

您可以使用简单的 protocolsubviews 属性来减少代码:

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/

相关文章:

ios - 快速将 GPS 元数据字典添加到使用 AVFoundation 拍摄的图像

objective-c - NSPredicate 正则表达式不起作用

ios - 在 Swift 中检查 UIButton 标题

swift - NSSegmentedControl 分段可选事件虽然禁用

ios - 将类类型传递给泛型

ios - 拖动创建一条线

objective-c - Objective-C 中 protobuf 编译文件的问题

ios - SKLightNodes 导致 SpriteKit 中的帧速率问题

ios - uitableviewcontroller 上带有按钮的工具栏 [Monotouch 如果可能的话]

objective-c - 将之前上传的项目从 Objective C 更改为 Swift