使用 Core Data 插入数据库时​​出现内存警告

Getting memory warning when inserting into database with Core Data

我要解释一下我的场景:

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

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

我发现的问题是我从服务中获取了大量 EntityB 个对象(大约 5000 个对象),并且我收到内存警告,即使在像这样的单独线程中进行解析和插入:

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
                });
            });

我需要将所有对象存储在数组中,以便稍后创建它们之间的关系,并将具有关系的模型保存在数据库中。我不知道更好的方法来做到这一点,有人可以帮助我吗?在这种情况下如何避免出现内存警告?

提前致谢

您不应在数组中维护数据的多个副本。您已经有了 JSON 对象。此外,您只需要一个后台线程 - 或者您可以只设置一个 activity 指示器几秒钟,而不必理会后台线程。

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

我在第一代 iPad 上用超过 100.000 条记录(JSON 字符串应用程序。60MB)做了类似的事情 iPad。

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

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

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