将数据更新传播到许多 ViewController 的传统架构是什么?
What is the conventional architecture to propagate data updates to many ViewControllers?
我正在开发一个具有三个视图的应用程序,这些视图同时显示在屏幕上并且共享相同的数据模型,一个 Swift 对象也有子对象。每个视图以不同的方式呈现数据,并为用户提供修改数据的方式,例如重新排序项目、adding/removing 项目等。此外,某些用户操作会触发对模型的异步更新,例如获取其他信息来自 API 的项目。我的目标是找到一种架构,使我能够通知每个视图的控制器数据更新,而无需在视图控制器之间强制通信。
解决这个问题的常规方法是什么?
常见的方法是订阅 NSNotification
以通知观察者已发生更新:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateData:) name:kAppDidUpdateDataNotification object:nil];
然后数据源可以向订阅者发送通知:
[[NSNotificationCenter defaultCenter] postNotificationName:kAppDidUpdateDataNotification
object:object];
另一种方法是共享数据源并使用 Key Value Observing on it. KVO lets you subscribe to updates on a keyPath
(like a property on your data source). KVO is a little hairy—I recommend using a library that wraps it into something that supports blocks, or maybe consider a framework like ReactiveCocoa that has similar properties. Note that you can also observe changes to collections 和 KVO,如果你有,这很好。一个 NSMutableArray
的项目,多个 table 视图控制器显示它们,并且您想做一些事情,比如在从数组中删除对象时动画删除特定索引处的行。由于您提到重新订购和 adding/removing 项,这可能特别适合您。
将委托列表添加到您的数据模型,每当事件发生时,遍历列表并通知其委托。这是 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通知中心应该只用于松散耦合的情况(即通知发送者和通知接收者彼此不了解);如果您的视图控制器对其共享数据模型有深入的了解,那么委托/多委托是更好的方法。
此外,根据您的问题,数据模型的生命周期可能独立于它的视图控制器(例如作为单例),或者由其中一个视图控制器管理。
我正在开发一个具有三个视图的应用程序,这些视图同时显示在屏幕上并且共享相同的数据模型,一个 Swift 对象也有子对象。每个视图以不同的方式呈现数据,并为用户提供修改数据的方式,例如重新排序项目、adding/removing 项目等。此外,某些用户操作会触发对模型的异步更新,例如获取其他信息来自 API 的项目。我的目标是找到一种架构,使我能够通知每个视图的控制器数据更新,而无需在视图控制器之间强制通信。
解决这个问题的常规方法是什么?
常见的方法是订阅 NSNotification
以通知观察者已发生更新:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateData:) name:kAppDidUpdateDataNotification object:nil];
然后数据源可以向订阅者发送通知:
[[NSNotificationCenter defaultCenter] postNotificationName:kAppDidUpdateDataNotification
object:object];
另一种方法是共享数据源并使用 Key Value Observing on it. KVO lets you subscribe to updates on a keyPath
(like a property on your data source). KVO is a little hairy—I recommend using a library that wraps it into something that supports blocks, or maybe consider a framework like ReactiveCocoa that has similar properties. Note that you can also observe changes to collections 和 KVO,如果你有,这很好。一个 NSMutableArray
的项目,多个 table 视图控制器显示它们,并且您想做一些事情,比如在从数组中删除对象时动画删除特定索引处的行。由于您提到重新订购和 adding/removing 项,这可能特别适合您。
将委托列表添加到您的数据模型,每当事件发生时,遍历列表并通知其委托。这是 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通知中心应该只用于松散耦合的情况(即通知发送者和通知接收者彼此不了解);如果您的视图控制器对其共享数据模型有深入的了解,那么委托/多委托是更好的方法。
此外,根据您的问题,数据模型的生命周期可能独立于它的视图控制器(例如作为单例),或者由其中一个视图控制器管理。