In my app I store data from a JSON file in this way (it's a example for an identity)
在我的应用程序中,我以这种方式存储JSON文件中的数据(这是标识的示例)
NSManagedObjectContext *context = [self managedObjectContext];
for (id element in array){
NSLog(@"element:%@", element);
Str *str = [NSEntityDescription insertNewObjectForEntityForName:@"Str" inManagedObjectContext:context];
Id_loc *loc = [NSEntityDescription insertNewObjectForEntityForName:@"Id_loc" inManagedObjectContext:context];
loc.id_loc = @"id_1";
[str addLocObject:loc];
}
The problem is that that I parse this JSON every day from a web service; so every day it can change data and number of its "Str" identity (an object of my JSON). The question is, what's the better solution to update my core data DB? I have two possibilities:
问题是,我每天都从web服务解析这个JSON;因此,它每天都可以更改其“Str”标识(我的JSON对象)的数据和编号。问题是,更新我的core data DB更好的解决方案是什么?我有两个可能性:
1- update my DB with NSFetchRequest, check if an element exist, and update it; if it not exist, I should create it. And finally if an object is not present in JSON but it's inside my core data DB, I should delete it, it's a complex series of controls.
1-用NSFetchRequest更新我的DB,检查是否存在一个元素,并更新它;如果它不存在,我应该创建它。最后,如果一个对象不在JSON中但是在我的core data DB中,我应该删除它,它是一系列复杂的控件。
2- delete all core data db and populate again with new JSON file.
2-删除所有core data db并重新填充新的JSON文件。
In your opinion, what's the better choice?
在你看来,什么是更好的选择?
I say you that in my app I must only read my db, and I don't need to delete or modify it when I use it.
我告诉你,在我的应用程序中,我只能读取我的db,我使用它时不需要删除或修改它。
2 个解决方案
#1
1
For my app - where I use CoreData as well - I decided to go with option 1, for several reasons.
对于我的应用程序——我也使用CoreData——我决定选择选项1,原因有很多。
First on all it's just a bit more coding, but performance is so much better with that approach. If you are planning to use NSFetchedResultController you should definitely go with update option. Otherwise it will listen to your changes and it will reload all the views so many times, because you delete all objects and readd them.
首先,它只是多了一点编码,但是使用这种方法的性能要好得多。如果您打算使用NSFetchedResultController,那么一定要使用update选项。否则,它将侦听您的更改,并多次重载所有视图,因为您将删除所有对象并读取它们。
Most important removing all objects is really expensive operation in CoreData because you have to fetch all objects first, than delete them one by one !!! It's really bad idea :) For several hundreds entries it's really taking application performance down if you are planning to do updates in background not blocking a screen during update process.
最重要的是删除所有对象是在CoreData中非常昂贵的操作,因为您必须首先获取所有对象,而不是逐个删除它们!!这是一个非常糟糕的想法:对于数百个条目,如果你打算在更新过程中不阻塞屏幕,那么它确实会降低应用程序的性能。
As an optimization I would recommend to keep on your server side timestamp for each object and pull only changes from last updated time on mobile side - incremental updates.
作为一种优化,我建议保持每个对象的服务器端时间戳,并且只从移动端上的上一次更新时间提取更改——增量更新。
#2
1
Option 1 is generally better but obviously can be more costly depending on the changes and batch management. Option 2 is always costly, but it less error prone. Option 2 adds constraints related to saving additional information (maybe not a concern at the moment).
选项1通常更好,但显然根据更改和批处理管理的不同,它的成本会更高。选项2总是代价高昂的,但是它不太容易出错。选项2增加了与保存附加信息相关的约束(目前可能不需要考虑)。
Ideally, you want to leverage an existing solution providing an implementation of option 1 which is tested and offers performance / memory efficiency options. Something like RestKit (which can use a temporary in-memory cache to find duplicates during the mapping process). As a side benefit, you can also simplify other mapping code you might have.
理想情况下,您希望利用现有的解决方案来提供选项1的实现,该方案被测试并提供性能/内存效率选项。类似RestKit(可以在映射过程中使用临时内存缓存来查找副本)。作为附带的好处,您还可以简化您可能拥有的其他映射代码。
#1
1
For my app - where I use CoreData as well - I decided to go with option 1, for several reasons.
对于我的应用程序——我也使用CoreData——我决定选择选项1,原因有很多。
First on all it's just a bit more coding, but performance is so much better with that approach. If you are planning to use NSFetchedResultController you should definitely go with update option. Otherwise it will listen to your changes and it will reload all the views so many times, because you delete all objects and readd them.
首先,它只是多了一点编码,但是使用这种方法的性能要好得多。如果您打算使用NSFetchedResultController,那么一定要使用update选项。否则,它将侦听您的更改,并多次重载所有视图,因为您将删除所有对象并读取它们。
Most important removing all objects is really expensive operation in CoreData because you have to fetch all objects first, than delete them one by one !!! It's really bad idea :) For several hundreds entries it's really taking application performance down if you are planning to do updates in background not blocking a screen during update process.
最重要的是删除所有对象是在CoreData中非常昂贵的操作,因为您必须首先获取所有对象,而不是逐个删除它们!!这是一个非常糟糕的想法:对于数百个条目,如果你打算在更新过程中不阻塞屏幕,那么它确实会降低应用程序的性能。
As an optimization I would recommend to keep on your server side timestamp for each object and pull only changes from last updated time on mobile side - incremental updates.
作为一种优化,我建议保持每个对象的服务器端时间戳,并且只从移动端上的上一次更新时间提取更改——增量更新。
#2
1
Option 1 is generally better but obviously can be more costly depending on the changes and batch management. Option 2 is always costly, but it less error prone. Option 2 adds constraints related to saving additional information (maybe not a concern at the moment).
选项1通常更好,但显然根据更改和批处理管理的不同,它的成本会更高。选项2总是代价高昂的,但是它不太容易出错。选项2增加了与保存附加信息相关的约束(目前可能不需要考虑)。
Ideally, you want to leverage an existing solution providing an implementation of option 1 which is tested and offers performance / memory efficiency options. Something like RestKit (which can use a temporary in-memory cache to find duplicates during the mapping process). As a side benefit, you can also simplify other mapping code you might have.
理想情况下,您希望利用现有的解决方案来提供选项1的实现,该方案被测试并提供性能/内存效率选项。类似RestKit(可以在映射过程中使用临时内存缓存来查找副本)。作为附带的好处,您还可以简化您可能拥有的其他映射代码。