我对经常必须处理100K插入,删除和更新与核心数据的应用工作。如果它在5K刀片上窒息,那么需要做一些优化。
首先,创建一些NSOperation子类来处理数据。覆盖它的-main方法来执行处理。但是,此方法不能保证在主线程上运行。事实上,它的目的是为了避免在主线程上执行代价昂贵的代码,从而导致严重冻结,从而影响用户体验。因此,在-main方法中,您需要创建另一个托管对象上下文,它是您的主线程托管对象上下文的子项。
- (void)main
{
NSManagedObjectContext *ctx = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[ctx setPersistentStoreCoordinator:mainManagedObjectContext.persistentStoreCoordinator];
[ctx setUndoManager:nil];
// Do your insertions here!
NSError *error = nil;
[ctx save:&error];
}
根据你的情况,我不认为你需要一个撤销管理器。由于核心数据正在跟踪您的更改,因此将会导致性能损失。
使用THIS上下文在-main方法中执行所有CRUD操作,然后保存该托管对象上下文。无论您的主线程的托管对象上下文拥有什么,都必须注册以响应名为NSManagedObjectContextDidSaveNotification的NSNotification。注册像这样:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mocDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:nil];
然后定义选择:
- (void)mocDidSaveNotification:(NSNotification *)notification
{
NSManagedObjectContext *ctx = [notification object];
if (ctx == mainManagedObjectContext) return;
[mainManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}
当这一切走到一起,它可以让你执行在后台线程长时间操作而不会阻塞UI线程。这种体系结构有几种不同的形式,但其核心主题是:在BG线程上处理,在主线程上合并,更新UI。还有一些需要注意的事项:(1)在处理过程中保持一个自动释放池,并且每隔一段时间耗尽一次以减少内存消耗。在我们的例子中,我们每1000个对象就做一次。根据您的需要进行调整,但请记住,根据每个对象所需的内存量,耗尽可能会很昂贵,因此您不想经常这样做。 (2)尽量减少你的数据到绝对的最低限度,你需要有一个功能的应用程序。通过减少要解析的数据量,可以减少保存所需的时间。 (3)通过使用这种多线程方法,您可以同时处理您的数据。因此,创建3-4个NSOperation子类的实例,每个实例只处理一部分数据,以便它们全部同时运行,从而导致分析数据集所需的实时时间更少。
这个问题是怎么发生的?我正在处理类似大小的数据集(如果不大),并且需要每天从Web服务中将其拉下一次。我正在考虑下载夜间准备的.sqlite文件与实际的Web服务。 – Augie 2012-07-10 20:51:47
我认为加载准备好的sqlite文件是这种情况下最好的解决方案,或者至少是最简单的一种。无论如何,其他解决方案太复杂,手机设备性能差。 – Matthes 2012-07-11 09:48:47