使用 managedObjectCache 时的 Restkit 映射

Posted

技术标签:

【中文标题】使用 managedObjectCache 时的 Restkit 映射【英文标题】:Restkit mapping while using managedObjectCache 【发布时间】:2015-05-20 17:19:58 【问题描述】:

我正在使用 Restkit 将大型数据集映射到核心数据。我正在调用从 Web 服务获取数据,将其存储在核心数据中,然后从核心数据中显示它。 这是我的代码。

+(void) setupManagedObjectStore

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
    NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];  
    RKManagedObjectStore *store = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];

    NSError *error = nil;
    BOOL success = RKEnsureDirectoryExistsAtPath(RKApplicationDataDirectory(), &error);   
    if (! success)
    
        NSLog(@"Failed to create Application Data Directory at path '%@': %@", RKApplicationDataDirectory(), error);
    

    NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"MyFile.sqlite"];

    //Does lightweight migration automatically
    NSDictionary *options = @
                          NSMigratePersistentStoresAutomaticallyOption : @YES,
                          NSInferMappingModelAutomaticallyOption : @YES
                          ;   
    NSPersistentStore *persistentStore = [store addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil withConfiguration:nil options:options error:&error]; 
    if (! persistentStore)
    
        NSLog(@"Failed adding persistent store at path '%@': %@", path, error);
      
    [store createManagedObjectContexts];   
    store.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:store.persistentStoreManagedObjectContext];

    [[RKObjectManager sharedManager] setManagedObjectStore:store];

获取数据,删除表中已有数据并添加新数据

-(void)getData:(SuccessBlock)successBlock withFailure:(FailureBlock)failureBlock objectId:(NSString *) objectId

    [self deleteData:objectId]; //Deletes the data from the entity
    NSString *path = [NSString stringWithFormat:@"getData/%@",objectId];
    [[RKObjectManager sharedManager] getObjectsAtPath:path parameters:nil
                                          success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult)
                                              NSLog(@"SUCCESS in getting data");
                                              if(successBlock)
                                                  successBlock([self getDataFromCoreData:objectId]);
                                              

                                          failure:^(RKObjectRequestOperation *operation, NSError *error)
                                              NSLog(@"FAILURE in getting data");                                          

                                          
 ];    


-(NSArray *)getDataFromCoreData : objectId

    NSArray *array = [[NSArray alloc] init];

    NSManagedObjectContext *context = [[[RKObjectManager sharedManager] managedObjectStore] mainQueueManagedObjectContext];
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"MyEntity"];
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"objectId= %@", objectId];

    NSError *error;
    array = [context executeFetchRequest:fetchRequest error:&error];
    return array;

我的核心数据模型有很多 1:many 关系,我的 Restkit 映射很慢,因此为了提高性能我添加了这行

store.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:store.persistentStoreManagedObjectContext];

这确实提高了性能,但在 deleteData() 调用之后,Restkit 映射似乎交替发生。

调用 getData - 1:getDataFromCoreData 返回数据 调用getData - 2:getDataFromCoreData 返回空数组,表为空 调用 getData - 3:getDataFromCoreData 返回数据 调用getData - 4:getDataFromCoreData返回空数组,表为空

如果我注释掉 store.managedObjectCache 行,一切正常,getDataFromCoreData 总是返回数据。但是 Restkit 映射变得超级慢。 我在 RKInMemoryManagedObjectCache 上找不到足够的文档来了解到底发生了什么......

有人能帮我理解为什么它会这样工作吗?或者建议一种更好的方法来提高 Restkit 映射性能?

编辑:添加删除代码

-(void)deleteData : objectId

    NSManagedObjectContext *context = [[[RKObjectManager sharedManager] managedObjectStore] mainQueueManagedObjectContext];
    NSArray *array = [self getDataFromCoreData: objectId];
    for (NSManagedObject *product in array)
          
        [context deleteObject:product];
    

【问题讨论】:

显示删除方法和你的映射代码 【参考方案1】:

我想通了。在 deleteData 方法调用之后,我必须执行 saveToPersistentStore。

我将 persistentStoreManagedObjectContext 用于 managedObjectCache 和 mainQueueManagedObjectContext 用于保存到核心数据和检索。 persistentStoreManagedObjectContext vs mainQueueManagedObjectContext

因此,在删除之后和进行 Web 服务调用之前使用 saveToPersistentStore 保存上下文可以解决问题。

【讨论】:

以上是关于使用 managedObjectCache 时的 Restkit 映射的主要内容,如果未能解决你的问题,请参考以下文章

使用 AudioQueueStart() 时的延迟

使用 Proguard 时的未知来源

Maven使用时的错误

在 Django 中使用 % url % 时的 NoReverseMatch

使用 UIStoryboards 时的最佳实践是啥?

使用 Python 处理 sql 时的撇号 (') 帮助