2012-03-07 11 views
1

最近コアデータを扱い始めましたが、テストではデータが実際にDBに保存されるのは約20%でした。残りの時間は、アプリが実行されている間だけ一時的に保存されます。再起動すると、最後に保存したデータが失われます。アプリケーションが終了した後に保存されたコアデータがアプリケーションの終了時間の80%を超えても残っていない

誰でも問題の原因を知ることができますか?

ここでは、コードです:

//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 

注:私のデータモデルもありますこれはage、location、nameという属性を持つ "Users"というエンティティを持っています。

+0

まあ、断続的なバグは見つけにくいので、可能な限りコードを投稿してください。別の言い方をすれば、MagicalRecord(https://github.com/magicalpanda/MagicalRecord)を見て、私は最近これを使用していて、多くの一般的なコアデータタスクのために自分の人生を楽にしました。 – allaire

+1

アプリが実行されていない場合、どのように保存しますか? – Mundi

+0

allaire、私はちょうど私のヘッダーと実装ファイルのコードを投稿しました。そして、私はMagicalRecordを見てみましょう、ありがとう! –

答えて

6

データは自動保存のために保存されていました。これは、各X(おそらく10、ドキュメントを確認する必要があります)秒間に発生します。それはfetchStuffにこのコードを追加し正常に動作しますが、それは自動的に可能性があるため:,ユーザが画面を終了するときにこれを実装する方が良いと思います

[documentation saveToURL:documentation.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) { 
if(success == YES) NSLog(@"Awesome, it's saved!"); 
}]; 

:保存を強制するために、私はこれを使ってきたはずですオートセーブで保存されます。

+1

ありがとう、これは私がこの問題のために見つけることができた唯一の解決策でした!数日間それを並べ替えることを試みている!他に誰も提案したことはありませんでした! – simonthumper

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]); 

OK ...それはあまりにも苦痛ではなかった...ただ保存するための呼び出しを削除し、いくつかの変更が行われていることをUIManagedDocumentを告げるコールに置き換えて、保存する必要があります。

+0

これはすぐに文書を保存するか、10秒待つか? –

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"); 
    } 
関連する問題