未保存托管对象上下文

时间:2014-04-05 22:45:24

标签: ios objective-c core-data nsmanagedobjectcontext

我正在尝试使用代表人的单元格加载表格视图,从核心数据加载。这就是我获取上下文的方式:

@property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;

...

- (NSManagedObjectContext*) managedObjectContext {
    if(!_managedObjectContext) {
        NSFileManager* manager= [NSFileManager defaultManager];
        NSURL* URL= [manager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;
        URL= [URL URLByAppendingPathComponent:@"PeopleDocument"];
        UIManagedDocument* document= [[UIManagedDocument alloc]initWithFileURL:URL];

        if([manager fileExistsAtPath:URL.path]) {
            [document openWithCompletionHandler:^(BOOL success) {
            }];
        } else {
            [document saveToURL:URL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
            }];
        }
        NSManagedObjectContext* context= [document managedObjectContext];
        _managedObjectContext= context;
    }
    return _managedObjectContext;
}

然后我第一次运行应用我插入一个新实体并保存上下文:

[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext: self.managedObjectContext];
[self.managedObjectContext save:NULL];

我还尝试记录save:的结果,它返回YES并且没有错误。但是上下文并没有真正保存:第二次运行应用程序时,获取的实体数组是空的。

更新

甚至发生了一些奇怪的事情:将this answer读到另一个类似的问题,我找到了一种方法来强制保存文档:

- (void) save {
    NSError *error = nil;

    if (![self.managedObjectContext save:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    [self.managedDocument saveToURL:self.managedDocument.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success)
    {
        NSLog(@"Saved: %d",success);
    }];

}

所以我第一次运行应用程序时执行此代码:

#if FIRST_TIME
    [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext: self.managedObjectContext];
    [self save];
#endif

之后,如果我将FIRST_TIME设置为零,那么第二次运行应用程序时,我会得到空记录。但是,如果我第三次运行应用程序,我再次将FIRST_TIME设置为1,那么我将获得之前创建的所有记录(以及创建的记录)。这意味着如果我创建并保存新实体,则会正确获取之前创建的所有实体,否则不会获取任何实体。

PS:我仔细检查过:托管对象上下文是self.managedDocument.managedObjectContext返回的确切内容。

1 个答案:

答案 0 :(得分:0)

我刚改变了创建托管对象上下文的方法。我没有使用UIManagedDocument,而是使用alloc + initWithConcurrencyType:创建了上下文,然后设置了它的持久性商店协调员:

- (NSManagedObjectContext*) managedObjectContext {
    if(!_managedObjectContext) {
        NSURL* URL= [[NSBundle mainBundle] URLForResource:@"People" withExtension:@"momd"];
        NSManagedObjectModel* model= [[NSManagedObjectModel alloc]initWithContentsOfURL:URL];
        NSPersistentStoreCoordinator* storeCoordinator= [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel: model];
        NSURL* storeURL= [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject;
        storeURL= [storeURL URLByAppendingPathComponent:@"MOC.sqlite"];

        NSError* error;
        [storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
        if(error) {
            NSLog(@"Cannot create new store %@",error);
            return nil;
        }

        _managedObjectContext= [[NSManagedObjectContext alloc]initWithConcurrencyType: NSMainQueueConcurrencyType];
        _managedObjectContext.persistentStoreCoordinator= storeCoordinator;
    }

    return _managedObjectContext;
}

我相信另一种方式也是正确的,但也许我不得不以另一种方式保存文件。