【问题标题】:How to trigger an action if a property of a array element changes?如果数组元素的属性发生变化,如何触发动作?
【发布时间】:2017-05-27 23:26:32
【问题描述】:

在 Swift 中,我有一个数据模型,它使用在表格视图中显示的项目数组。
数据模型可以通过各种来源随时更改,我想在更改时重新加载表格视图。

如果项目数组本身发生变化,这非常简单,例如通过为数据模型的数组属性分配一个新数组:setter 可以触发重新加载,例如由 KVO 提供。
但是,如果仅通过更改其中一个属性来更改数组元素(项),则表视图重新加载必须由项属性的设置器触发。
如果每个项目都有一个对存储项目数组的数据模型的引用,这将是可能的:使用这个引用,数据模型可以被通知项目的变化,并触发表视图的重新加载。但是,我认为如果数组元素引用了它的数组,这不是一种好的编程风格。

因此,如果数组元素(项目)只能由数据模型本身更改,则另一种选择。在这种情况下,项目属性的设置器应该仅可用于数据模型。 实现这一点的一种方法是在同一个文件中定义用户模型类和项目类,并将项目的属性设置器声明为fileprivate。然后,只有数据模型可以更改项目的属性。 但是仅出于这个原因将两个类都定义在一个文件中在我看来不是很优雅。

有没有更直接的方法来处理这种情况?

【问题讨论】:

    标签: arrays swift key-value-observing access-control


    【解决方案1】:

    另一种解决方案是使用协议编写您自己的简单观察系统。优点是它使所有内容都保持更松散的耦合,并且可以轻松扩展以供将来使用:

    class MyElement {
        var property = "Test" {
            didSet {
                guard property != oldValue else { return }
                for observer in observers {
                    observer.didChangeProperty(element: self)
                }
            }
        }
    
        var observers: [MyElementObserver] = []
    }
    
    protocol MyElementObserver {
        func didChangeProperty(element: MyElement)
    }
    
    extension MyElementObserver {
        func didChangeProperty(element: MyElement) {}
    }
    

    然后您可以使您的视图符合此协议并处理将自己添加到每个元素的 observers 数组中,或者您可以走可能更干净的路线并制作一个 MyDataModelObserver 协议,然后制作您的数据模型观察其元素并将这些通知传递给观察者(即视图)。

    【讨论】:

    • 谢谢,@andyvn22。会调查的!
    猜你喜欢
    • 1970-01-01
    • 2022-01-20
    • 2021-03-06
    • 2017-02-03
    • 2016-11-18
    • 1970-01-01
    • 2015-01-02
    • 1970-01-01
    • 2021-06-27
    相关资源
    最近更新 更多