1

概要

  • Coreデータを使用しているiOSプロジェクトがあります
  • オブジェクトを挿入しているので、それを保存したいと思います。
  • 保存が機能するかどうかはわかりません。
  • アプリがバックグラウンドになると、保存が機能しているようです
  • シミュレータを使用しているときに、Xcodeの[停止]ボタンをクリックすると、保存が機能していないようです。

質問

  1. 保存は実際に行われていますか?
  2. ビューベースのアプリを作成したために問題が発生していますか(コアデータのチェックボックスが利用できませんでした)?

従う手順

  • 私はそれをテストするためにシミュレーターを使用しています。
  • オブジェクトを挿入します(コードは次のセクションにあります)
  • 挿入したオブジェクトを保存します(コードは次のセクションにあります)
  • Xcodeの停止ボタンを押してアプリの実行を停止します

出力に気づいた

setBeforeSave.count = 1
setAfterSave.count = 0
  • 保存する前に、NSManagedObjectContextメソッドinsertedObjectsは1つのオブジェクトを返します
  • 保存する前に、NSManagedObjectContextメソッドinsertedObjectsは0個のオブジェクトを返します
  • Xcodeの停止ボタンが押されたとき、およびアプリが再起動されたとき、以前のデータは利用できません(xcodeで停止をクリックしたためです)
  • managedObjectContextはnilではありません
  • NSManagedObjectContextメソッドはをsave:返しますYES

オブジェクトを挿入するコード

Test *test = [NSEntityDescription insertNewObjectForEntityForName:@"Test" inManagedObjectContext:self.database.managedObjectContext];

保存するコード:

//database is a property of the type UIManagedDocument

NSSet *setBeforeSave = [self.database.managedObjectContext insertedObjects];
NSLog(@"setBeforeSave.count = %i", setBeforeSave.count);

NSError *error = nil;

if(![self.database.managedObjectContext save:&error])
    NSLog(@"error = %@", error);    

NSSet *setAfterSave = [self.database.managedObjectContext insertedObjects];
NSLog(@"setAfterSave.count = %i", setAfterSave.count);
4

1 に答える 1

5

UIManagedDocumentのドキュメントによると、どちらの内部管理コンテキストでもsaveを呼び出さないでください。代わりに、データを保存する場合は、次の2つのいずれかを実行する必要があります。

  1. undoManagerを使用します。これにより、コンテキストがダーティにマークされ、保存の準備が整います。

  2. [document updateChangeCount:UIDocumentChangeDone]を呼び出します。

したがって、あなたの場合、その保存呼び出しを次のように置き換える必要があります。

[self.database updateChangeCount:UIDocumentChangeDone];

そして、あなたのデータは保存されます。

編集

追加の詳細を提供するため。UIManagedDocumentには、親子関係にある2つのMOCがあります。子は、document.managedObjectContextを呼び出すときに取得する子です。これで、NSManagedObjectContextに親がある場合、変更を親に伝達する通常の方法は、save:を呼び出すことです。ただし、UIManagedDocuememtは他の処理を実行し、そのドキュメントには、親コンテキストまたは子コンテキストのいずれかでsaveを呼び出さないように具体的に記載されています。

では、どうやって物を救うのでしょうか?さて、UIManagedDocumentに、それが「ダーティ」であり、保存する必要があることを伝えます。これを行う2つの方法は、undoManagerを使用するか、updateChangeCountを呼び出すことです。

これらのいずれかを実行する場合、UIManagedDocumentの内部は、親コンテキストに変更が通知されることを確認します。将来のある時点で、親は実際のバッキングストア(つまり、ディスク上のファイル)への変更を有効にします。

さらに、コンテキストが「保存」されると、変更されたオブジェクトへの参照が保持される場合と保持されない場合があります。保存されたオブジェクトを保持するか、解放するかを指定するプロパティを設定できます。

うまくいけば、それはあなたの問題に対処します。

ただし、要約すると、元の回答を参照してください。

ところで、コマンドライン引数に「-com.apple.CoreData.SQLDebug 1」を追加することで、SQLストアが実行していることのログを実際に確認できます。これは、[スキームの編集]ダイアログで行います。

于 2012-04-17T03:25:43.487 に答える