我正在尝试使用代表人的单元格加载表格视图,从核心数据加载。这就是我获取上下文的方式:
@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
返回的确切内容。
答案 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;
}
我相信另一种方式也是正确的,但也许我不得不以另一种方式保存文件。