RestKit:'NSInternalInconsistencyException',原因:'无法执行映射:没有指定`managedObjectContext`

时间:2014-12-08 02:57:18

标签: ios core-data restkit restkit-0.20

我收到以下错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unable to perform mapping: No `managedObjectContext` assigned. (Mapping response.URL = https://www.someurl.com/lastrequest=2014-12-08T02%3A44%3A52Z)'

应用停在RKResponseMapperOperation.m中的以下行:

- (RKMappingResult *)performMappingWithObject:(id)sourceObject error:(NSError **)error
{

    NSLog(@"managedObjectContext: %@,    Source Object: %@        Error: %@", self.managedObjectContext, sourceObject, (*error).description);
    NSAssert(self.managedObjectContext, @"Unable to perform mapping: No `managedObjectContext` assigned. (Mapping response.URL = %@)", self.response.URL);
....

我注意到上述方法在应用程序崩溃之前被称为27(此数字不同)。在每个实例中,存在NSManagedObjectContext,即下面的行:

2014-12-07 18:44:48.721 MyApp[19011:3258405] managedObjectContext:managedObjectContext: <NSManagedObjectContext: 0x1701f5800>,    Source Object: {
    friends =     (
    );
}        Error: (null)

然而,在它崩溃之前,NSManagedObjectContext为null:

2014-12-07 18:44:53.454 MyApp[19011:3258404] managedObjectContext: (null),    Source Object: {
    friends =     (
    );
}        Error: (null)

由于应用程序在崩溃之前正常运行一段时间,我不确定如何解决这个问题。任何指针都将非常感激。

*编辑*

在Appdelegaate。当用户登录时,此方法在viewDidLoad中调用一次。

- (RKManagedObjectStore *)managedObjectStore
{
    if (!_managedObjectStore && [Persistence loggedIn])
    {
        NSError * error;
        NSURL * modelURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"App" ofType:@"momd"]];
        NSManagedObjectModel * managedObjectModel = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] mutableCopy];
        self.managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];

        [_managedObjectStore createPersistentStoreCoordinator];

        NSArray * searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString * documentPath = [searchPaths objectAtIndex:0];

        NSString *dbName = [NSString stringWithFormat:@"%@App%@.sqlite", documentPath, [Persistence username]];
        NSPersistentStore * persistentStore = [_managedObjectStore addSQLitePersistentStoreAtPath:dbName
                                                                           fromSeedDatabaseAtPath:nil
                                                                                withConfiguration:nil
                                                                                          options:[self optionsForSqliteStore]
                                                                                            error:&error];
        NSAssert(persistentStore, @"Failed to add persistent store with error: %@", error);

        NSLog(@"Path: %@", dbName);

        if(!persistentStore)
        {
            NSLog(@"Failed to add persistent store: %@", error);
        }

        [_managedObjectStore createManagedObjectContexts];
        self.managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];

        return self.managedObjectStore;
    }

    return _managedObjectStore;
}

- (id)optionsForSqliteStore
{
    return @{
             NSInferMappingModelAutomaticallyOption: @YES,
             NSMigratePersistentStoresAutomaticallyOption: @YES
             };
}

创建MOC: 对于Core Data堆栈,我使用了在Xcode中创建项目时提供的AppDelegate中的默认核心数据代码。

- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}

MOC运作:

- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
             // Replace this implementation with code to handle the error appropriately.
             // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        } 
    }
}

在App中,以下方法用于设置,获取和清除ObjectManager:

- (void)refreshMOC
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    self.objectManager = [self getObjectManager];

    self.objectManager.managedObjectStore = appDelegate.managedObjectStore;
    self.objectManager.managedObjectStore.managedObjectCache = appDelegate.managedObjectStore.managedObjectCache;
    self.managedObjectContext = self.objectManager.managedObjectStore.mainQueueManagedObjectContext;
}

- (RKObjectManager *)setupObjectManager
{
    NSURL *baseURL = [NSURL URLWithString:kBaseURL];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:baseURL];
    RKObjectManager *manager = [[RKObjectManager alloc]initWithHTTPClient:httpClient];
    [manager.HTTPClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
    [manager.HTTPClient setParameterEncoding:AFJSONParameterEncoding];
    [RKMIMETypeSerialization registeredMIMETypes];
    [RKObjectManager setSharedManager:manager];

    return [RKObjectManager sharedManager];
}

- (RKObjectManager *)getObjectManager
{
    self.objectManager = (!self.objectManager) ?  [self setupObjectManager] : self.objectManager;
    return self.objectManager;
}

- (RKObjectManager*)newObjectManager
{
    [self clearRKObjectManager];
    return [self getObjectManager];
}

- (void)clearRKObjectManager
{
    if (self.objectManager)
    {
        self.objectManager = nil;
    }
}

1 个答案:

答案 0 :(得分:1)

删除所有应用委托模板Core Data方法。当您使用RestKit并创建托管对象存储时,您要求RestKit为您管理Core Data堆栈,以便不需要其他方法(并使事情混淆)。

当您需要MOC时,从托管对象库中获取它/。

注意,以上内容也适用于保存,因为您需要使用RestKit方法保存到持久性存储,而不是仅保存单个MOC。