我正在开发一个具有三个视图的应用程序,这三个视图同时在屏幕上并且共享相同的数据模型,一个也有子对象的Swift对象。每个视图以不同的方式呈现数据,并为用户提供修改数据的方式,例如重新排序项目,添加/删除项目等。此外,某些用户操作会触发对模型的异步更新,例如获取项目的其他信息来自API。我的目标是找到一种架构,允许我通知每个视图的控制器数据更新,而不必在视图控制器之间进行必要的通信。
这个问题的传统方法是什么?
答案 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通知中心只应用于松散耦合的情况(即通知发送方和通知接收方不能很好地相互了解);如果您的视图控制器对其共享数据模型有深入的了解,那么委托/多代表是一种更好的方法。
此外,根据您的问题,数据模型的生命周期可能与其视图控制器无关(例如,作为单例),或由其中一个视图控制器管理。