将大量数据存储到Core Data中

时间:2016-07-04 21:36:29

标签: ios performance core-data optimization large-data

每当用户刷新页面时,我都会以JSON格式(超过2000个实体)将大量数据加载到Core Data中。我现在正在做的工作正常,但只是耗费时间。我正在考虑使用某种分页,但这需要后端修改。希望有人可以帮助我优化流程。或者指出另一种在iOS中存储大量数据的解决方案。

以下是大部分时间花费的部分:

[moc performBlock:^{
    for (NSDictionary *dictionary in dataObjectsArray) {
        NSPredicate *predicate = [ObjectA predicateWithDictionary:dictionary];
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:ENTITY_NAME];
        request.predicate = predicate;

        NSError *error;
        NSArray *fetchedObjects = [moc executeFetchRequest:request
                                                     error:&error];
        ObjectA *objectATemp = (ObjectA *)[fetchedObjects lastObject];
        if (!objectATemp) {
            NSEntityDescription *entityDescription = [NSEntityDescription entityForName:ENTITY_NAME
                                                                 inManagedObjectContext:moc];
            objectATemp = [[ObjectA alloc] initWithEntity:entityDescription
                           insertIntoManagedObjectContext:moc];
        }

        [ObjectA setObjectA:objectATemp
                 dictionary:dictionary];

        // check if user already liked the ObjectA
        ObjectB *likedObject = [ObjectB objectBWithId:objectATemp.id];
        if (likedObject &&
            !objectATemp.user_liked.boolValue) {
            [likedObject.managedObjectContext deleteObject:likedObject];
        }
    }

    NSError *error;
    if ([moc hasChanges] &&
        ![moc save:&error]) {
        NSLog(@"%@", error);
    }

    // saving Context
    NSManagedObjectContext *managedObjectContext = [self newManagedObjectContext];
    [managedObjectContext performBlock:^{
        NSError *error;
        if ([managedObjectContext hasChanges] &&
            ![managedObjectContext save:&error]) {
            NSLog(@"%@", error);
        }

        if (completionHandler) {
            completionHandler();
        }
    }];
}];

任何建议都很高兴。

2 个答案:

答案 0 :(得分:3)

使用Core Data存储大量数据不是问题; 2000年的记录甚至不是很多"。每次用户点击按钮时保存大量新数据都会很慢。最好的解决方案是不需要每隔时间存储所有数据

但您的代码中也存在一些显着的低效率。

您在每次循环中都会执行获取请求。假设您的dataObjectsArray包含2000个对象,那就是2000次提取。这是获取数据的最有效方法。如果你可以进行一次获取,或者一次可以获取100或200个对象而不是每次传递2000个对象,你将获得重大改进。很难说出最好的方法是什么,因为你没有描述你编码调用的谓词或其他方法,但这将是第一件要做的事情,这将是最大的改进。如果您无法以较小的块获取数据,那么可以至少以较大的数据处理它。您可能需要对setObjectA:dictionary:objectBWithID:等方法进行更改

此外,每次循环运行时,您的某些对象都是相同的。如果一个对象每次都相同,则创建一次,而不是(可能)2000次。例如,entityDescription。这比成千上万的获取请求要少得多,但它应该提供一些小改进。

答案 1 :(得分:0)

如果您的用户不会同时看到所有2000个,您可以尝试在第一时间下载100或200个实体并将其显示给您的用户并在后台下载其余实体。另一种方法是在你说的后端使用分页。