将数据更新传播到许多ViewControllers的传统架构是什么?

时间:2015-03-14 01:06:49

标签: ios cocoa-touch

我正在开发一个具有三个视图的应用程序,这三个视图同时在屏幕上并且共享相同的数据模型,一个也有子对象的Swift对象。每个视图以不同的方式呈现数据,并为用户提供修改数据的方式,例如重新排序项目,添加/删除项目等。此外,某些用户操作会触发对模型的异步更新,例如获取项目的其他信息来自API。我的目标是找到一种架构,允许我通知每个视图的控制器数据更新,而不必在视图控制器之间进行必要的通信。

这个问题的传统方法是什么?

2 个答案:

答案 0 :(得分:0)

常见的方法是订阅NSNotification,通知观察者发生了更新:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateData:) name:kAppDidUpdateDataNotification object:nil];

然后数据源可以向订阅者发送通知:

[[NSNotificationCenter defaultCenter] postNotificationName:kAppDidUpdateDataNotification
                                                    object:object];

另一种方法是拥有共享数据源并在其上使用Key Value Observing。 KVO允许您订阅keyPath上的更新(如数据源上的属性)。 KVO有点毛茸茸 - 我建议使用一个将它包装成支持块的东西的库,或者考虑像ReactiveCocoa这样具有类似属性的框架。请注意,您也可以使用KVO observe changes to collections,如果您有KVO一个NSMutableArray个项目,其中有多个表视图控制器显示它们,并且您希望在从数组中删除对象时,为特定索引处的行删除设置动画。由于您提到了重新订购和添加/删除项目,这可能特别适合您。

答案 1 :(得分:0)

向数据模型添加委托列表,每当事件发生时,循环遍历列表并通知其委托。这是Objective-C委托模式的扩展,与通知中心的addObserver / removeObserver非常相似。

protocol DataModelDelegate {
    func dataModel(dataModel: DataModel, didFetchData data: String) // Or any other events
}

class DataModel {
    private delegates = [DataModelDelegates]()

    func addDelegate(delegate: DataModelDelegate) { delegates.append(delegate) }
    func removeDelegate(delegate: DataModelDelegate) { // Remove `delegate` from `delegates` }

    func dataFetched(data: String) { // Or any other events
        for d in delegates { d.dataModel(self, didFetchData: data) }
    }
}

...

class ViewController1: UIViewController, DataModelDelegate {
    private dataModel: DataModel!

    init(dataModel: DataModel) {
        ...
        self.dataModel = dataModel
        dataModel.addDelegate(self)
        ...
    }

    deinit {
        // Retain cycle without this!
        dataModel.removeDelegate(self)
    }

    func dataModel(dataModel: DataModel, didFetchData data: String) {
        // Update UI, etc
    }

}

通知中心也将完成这项工作,但IMO通知中心只应用于松散耦合的情况(即通知发送方和通知接收方不能很好地相互了解);如果您的视图控制器对其共享数据模型有深入的了解,那么委托/多代表是一种更好的方法。

此外,根据您的问题,数据模型的生命周期可能与其视图控制器无关(例如,作为单例),或由其中一个视图控制器管理。