使用 Core Data 插入数据库时出现内存警告
Getting memory warning when inserting into database with Core Data
我要解释一下我的场景:
我的数据模型中有几个实体,它们之间存在一对多关系,假设它们是 EntityA
和 EntityB
。我向 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 条记录。
我要解释一下我的场景:
我的数据模型中有几个实体,它们之间存在一对多关系,假设它们是 EntityA
和 EntityB
。我向 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 条记录。