我最近开始处理Core Data,在我的测试中,我发现大约有20%的时间数据实际保存到数据库中。剩下的时间,它只是临时保存,而应用程序正在运行。如果我重新启动,我保存的最后一个数据会丢失。
有谁知道问题可能是什么?
以下是代码:
//Save data
NSEntityDescription *users = [NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:document.managedObjectContext];
[users setValue:@"Name Test" forKey:@"name"];
[users setValue:[NSNumber numberWithInt:20] forKey:@"age"];
[users setValue:@"Some Country" forKey:@"location"];
//Debugging
//no error ever shows up
NSError *error;
if(![document.managedObjectContext save:&error]) {
NSLog(@"Error: %@", error);
}
//this is just to show that the problem may not be with my UIManagedDocument (self.document), since the NSLog never gets called.
if(self.document.documentState != UIDocumentStateNormal) {
NSLog(@"Document is not opened");
}
//End of debugging
//Fetch all the data from the entity
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"Users"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
fetch.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *results = [document.managedObjectContext executeFetchRequest:fetch error:nil];
NSLog(@"Results on the database: %d", [results count]);
document
是同一件事(至少在大多数情况下我希望如此)self.document
;它只是该代码所在方法的一个参数。
这是我的.h和.m的代码:
·H
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface CoreDataViewController : UIViewController
@property (nonatomic, strong) UIManagedDocument *document;
@end
的.m:
#import "CoreDataViewController.h"
@implementation CoreDataViewController
@synthesize document = _document;
- (void)fetchStuff:(UIManagedDocument *)document {
//Save data
NSEntityDescription *users = [NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:document.managedObjectContext];
[users setValue:@"Name Test" forKey:@"name"];
[users setValue:[NSNumber numberWithInt:20] forKey:@"age"];
[users setValue:@"Some Country" forKey:@"location"];
//Debugging
//no error ever shows up
NSError *error;
if(![document.managedObjectContext save:&error]) {
NSLog(@"Error: %@", error);
}
//this is just to show that the problem may not be with my UIManagedDocument (self.document), since the NSLog never gets called.
if(document.documentState != UIDocumentStateNormal) {
NSLog(@"Document is not opened");
}
//End of debugging
//Fetch all the data from the entity
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"Users"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
fetch.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *results = [document.managedObjectContext executeFetchRequest:fetch error:nil];
NSLog(@"Results on the database: %d", [results count]);
}
- (void)useDocument {
if(![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]]) {
[self.document saveToURL:self.document.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
if(success == YES) NSLog(@"created");
[self fetchStuff:self.document];
}];
} else if(self.document.documentState == UIDocumentStateClosed) {
[self.document openWithCompletionHandler:^(BOOL success) {
if(success == YES) NSLog(@"opened");
[self fetchStuff:self.document];
}];
} else if(self.document.documentState == UIDocumentStateNormal) {
[self fetchStuff:self.document];
}
}
- (void)setDocument:(UIManagedDocument *)document {
if(_document != document) {
_document = document;
[self useDocument];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(!self.document) {
NSURL *url = [[[NSFileManager defaultManager]URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"Database"];
self.document = [[UIManagedDocument alloc]initWithFileURL:url];
}
}
@end
注意:还有我的数据模型,它有一个名为“Users”的实体,其属性为age,location,name。
答案 0 :(得分:6)
有时因为自动保存而保存数据,每次X(可能是10,我需要检查文档)秒发生。为了强制保存,我应该使用它:
[documentation saveToURL:documentation.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
if(success == YES) NSLog(@"Awesome, it's saved!");
}];
虽然将此代码添加到fetchStuff中可以正常工作,但最好在用户退出屏幕时实现此功能,因为它可以通过自动保存自动保存。
答案 1 :(得分:2)
您不应该在UIManagedDocument MOC上调用save。这是您的代码的编辑版本。请试一试。
//Save data
NSEntityDescription *users = [NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:document.managedObjectContext];
[users setValue:@"Name Test" forKey:@"name"];
[users setValue:[NSNumber numberWithInt:20] forKey:@"age"];
[users setValue:@"Some Country" forKey:@"location"];
// Removed save on UIMDMOC - We let auto-save do the work
// However, we have to tell the document that it needs to
// be saved. Now, the changes in the "main" MOC will get pushed
// to the "parent" MOC, and when appropriate, will get save to disk.
[document updateChangeCount:UIDocumentChangeDone];
if(self.document.documentState != UIDocumentStateNormal) {
NSLog(@"Document is not opened");
}
//Fetch all the data from the entity
NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"Users"];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
fetch.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *results = [document.managedObjectContext executeFetchRequest:fetch error:nil];
NSLog(@"Results on the database: %d", [results count]);
好的......这不是太痛苦...只是删除了保存的调用,并用一个告诉UIManagedDocument的调用替换了它已经进行了一些更改,并且需要保存。
答案 2 :(得分:0)
Record *newentry = [NSEntityDescription insertNewObjectForEntityForName:@"Record" inManagedObjectContext:self.mManagedObjectContext];
newentry.code = entryStr;
NSError *error;
if ([self.mManagedObjectContext save:&error])
{
NSLog(@"save successfully");
}
else
{
NSLog(@"fail to save");
}