最佳实践 - iOS 中的 NSManagedObjectContextObjectsDidChangeNotification
我正在使用 Core Data 编写我的第一个综合应用程序,我想看看跟踪各种对象更改/更新/删除的最佳方法是什么。例如,我有一个 Notes 实体和一个 Location 实体,以及它们之间的一对一关系,其想法是每个注释都可以标记其位置。然后我有一个 UITableView 和一个 fetchedResultsController 驱动笔记列表(您可以在其中添加新笔记并附加日期和位置),但我还有另外 2 个视图控制器,一个带有地图视图,一个带有日历视图。地图视图获取位置中的所有位置并将其显示在地图上。日历视图基本上再次从 Notes 获取所有数据,并将其显示在日历视图中。 我应该如何跟踪日历和地图视图中注释和位置的更改?在 viewDidLoad 中加载它们一次很容易,但是我应该如何跟踪所有更改,以便当用户重新访问地图视图时(例如)他/她也可以看到最新的数据。
我破译的一种方法是在地图视图和日历视图中监听 NSManagedObjectContextObjectsDidChangeNotification 中的通知。每次保存时,这似乎都会从托管上下文中返回所有插入、删除和更新的对象。然后我可以浏览这些对象并查看是否需要更新我的视图。这就是我的想法:
在 MapViewController viewDidLoad:
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(objectChangedNotificationReceived:)
name: NSManagedObjectContextObjectsDidChangeNotification
object: context];
然后:
- (void) objectChangedNotificationReceived: (NSNotification *) notification
{
NSArray* insertedObjects = [[notification userInfo]
objectForKey:NSInsertedObjectsKey] ;
NSArray* deletedObjects = [[notification userInfo]
objectForKey:NSDeletedObjectsKey] ;
NSArray* updatedObjects = [[notification userInfo]
objectForKey:NSUpdatedObjectsKey] ;
NSLog(@"insertObjects: %@", [insertedObjects description]);
NSLog(@"deletedObjects: %@", [deletedObjects description]);
NSLog(@"updatedObjects: %@", [updatedObjects description]);
for (NSManagedObject *obj in insertedObjects) {
if ([obj class] == [Location class]) {
NSLog(@"adding a new location");
Location *locationObj = (Location *) obj;
[self.mapview addAnnotation: locationObj];
}
}
}
这看起来正确吗?似乎要在每个视图控制器中放入大量冗余代码,尤其是当我对多个 NSManagedObject 感兴趣时。我还缺少其他一些技术吗?
I am writing my first comprehensive app using Core Data, and I want to see what the best way to keep track of various object changes / updates / deletes is. For example, I have a Notes entity and a Location entity, and a one-to-one relationship between them, the idea being that each note could have its location tagged. I then have a UITableView with a fetchedResultsController driving the list of notes (where you can add new notes and attach a date and location to them), but then I have 2 other view controllers, one with a map view and one with a calendar view. The map view fetches all the locations in Location and displays them on a map. The calendar view basically gets all the data from Notes again and just shows it in a calendar view.
How should I keep track of changes to Notes and Location in my calendar and map view? It's easy to load them up once in viewDidLoad, but how should I keep track of all the changes, so that when the user revisits the mapview (for e.g.) he/she sees the latest data as well.
The one way I've deciphered is to listen for notifications in NSManagedObjectContextObjectsDidChangeNotification, in both the maps view and the calendar view. This seems to return all the inserted, deleted and updated objects from a managed context, each time there's a save. I could then go through these objects and see if I need to update my view. This is how I'm thinking of doing it:
In MapViewController viewDidLoad:
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(objectChangedNotificationReceived:)
name: NSManagedObjectContextObjectsDidChangeNotification
object: context];
Then:
- (void) objectChangedNotificationReceived: (NSNotification *) notification
{
NSArray* insertedObjects = [[notification userInfo]
objectForKey:NSInsertedObjectsKey] ;
NSArray* deletedObjects = [[notification userInfo]
objectForKey:NSDeletedObjectsKey] ;
NSArray* updatedObjects = [[notification userInfo]
objectForKey:NSUpdatedObjectsKey] ;
NSLog(@"insertObjects: %@", [insertedObjects description]);
NSLog(@"deletedObjects: %@", [deletedObjects description]);
NSLog(@"updatedObjects: %@", [updatedObjects description]);
for (NSManagedObject *obj in insertedObjects) {
if ([obj class] == [Location class]) {
NSLog(@"adding a new location");
Location *locationObj = (Location *) obj;
[self.mapview addAnnotation: locationObj];
}
}
}
Does this seem about right? It seems like a lot of redundant code to put into each view controller, especially if I'm interested in more than one NSManagedObject. Is there some other technique that I'm missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
NSFetchedResultsController 似乎符合您的要求。它将有效地管理核心数据的数据处理。您可以为日历视图控制器和地图视图控制器重复使用相同的提取请求。
NSFetchedResultsController seems to fit your requirement. It will efficiently manage the data handling from the Core Data. You reuse the same fetch request for both of your calendar view controller and map view controller.
为什么不能直接在 viewWillLoad 或 viewDidLoad 方法上从 CoreData 获取最新数据。这将确保您拥有最新的对象。
看起来这会更加模块化和干净。
Why can't you just fetch the latest data directly from CoreData on the viewWillLoad or viewDidLoad method. This will ensure that you have the latest objects.
Seems like that would be more modular and cleaner.