使用Core Data插入数据库时​​获取内存警告

时间:2015-01-02 12:28:35

标签: ios core-data memory-management concurrency

我要解释我的情景:

我的数据模型中有几个实体,它们之间存在多对多的关系,我们说它们是EntityAEntityB。我要求所有这些实体'数据到REST服务,我收到JSON格式的所有信息,我解析它,然后我创建相应的对象。

服务'请求是异步执行的,我将最终得到的对象存储在两个NSMutableArray中,一个用于EntityA个对象,另一个用于EntityB个对象。获得所有对象后,我将EntityB的对象添加到NSSet中的EntityA,根据需要对关系进行建模。最后,我保存了上下文。

我发现的问题是我从服务中获得了大量EntityB个对象(5000个对象aprox),我得到了内存警告,即使解析并插入分离的线程,如下所示:

dispatch_queue_t queue = dispatch_queue_create(dataLoadQueue, NULL);
            dispatch_async(queue, ^{
                NSPersistentStoreCoordinator *mainThreadContextStoreCoordinator = [self.context persistentStoreCoordinator];
                NSManagedObjectContext *tmpContext = [[NSManagedObjectContext alloc] init];
                [tmpContext setPersistentStoreCoordinator:mainThreadContextStoreCoordinator];

                __block int count=0;

                for (NSDictionary *item in self.JSONObjects) {
                    dispatch_queue_t queue = dispatch_queue_create(dataParseQueue, NULL);
                    dispatch_async(queue, ^{
                        EntityB *entityB = [entitiesDao createEntityB:item];

                        if (entityB != nil) {
                            [self insertEntityB:entityB inContext:tmpContext];
                            [self.entityBArray addObject:entityB];
                        }

                        count++;
                    });
                }

                if (count == self.JSONObjects.count) {

                    for (EntityB *entityB in self.entityBArray) {
                            [self linkEntityA:[entityB.entityAId integerValue] toEntityB:entityB];
                    }

                    [self.context save:nil];
                }

                dispatch_async(dispatch_get_main_queue(), ^{
                    //finalization
                });
            });

我需要将所有对象存储在数组中以便以后创建它们之间的关系,并使用数据库中的关系保存模型。我不知道更好的方法,有人可以帮助我吗?在这种情况下,我怎么能避免记忆?

提前致谢

1 个答案:

答案 0 :(得分:0)

您不应该在数组中维护数据的多个副本。您已经拥有JSON对象。此外,您只需要一个后台线程 - 或者您可以在几秒钟内设置一个活动指示器而不用担心后台线程。

首先创建您的实体entityA对象并保存上下文。然后创建您的entityB对象并根据需要检索entityA对象以设置关系。

我在第一代iPad上做了超过100.000条记录(JSON字符串应用程序.60MB),没有任何问题。

有效的内存管理技术也是将关键部分包含在自动释放池中。

@autorelease {
   // memory intensive operation, e.g. in a loop
}

注意:出于性能原因,通常建议分批保存,例如每插入500-1000条记录。