データにNSManagedObjectサブクラスを使用するNSPersistentDocumentサブクラスがあります。
新しいドキュメントが開かれると、データ構造の初期化を行います(わずかな量の入力フィールド)。私が気付いたのは、無題のドキュメントが自動保存され、アプリケーションを再度開くと、そのドキュメントが読み込まれることです。アプリケーションが終了しても、ユーザーは(デフォルトでは)保存ダイアログを表示されません。ウィンドウが閉じると、ユーザーは閉じます。
最初の質問:
ユーザーがアプリケーションを終了したときに保存ダイアログを呼び出したい。この無題のドキュメントを(通常の状況では)ぶらぶらさせたくありません。私はそれを保存するかゴミ箱に捨てたいのです。
私は記入しようとしました:
- (void)applicationWillTerminate:(NSNotification *)aNotification
保存するドキュメントをトリガーするため。save:
この時点でコンテキストを呼び出すと、エラーが発生します。私の知る限り、これはユーザーがまだ自分でファイルを保存していないためです。さらに、保存せずにウィンドウを呼び出す[self close];
か閉じます。[[self windowForSheet] close];
保存ダイアログを強制的に表示するにはどうすればよいですか?無題のドキュメントをゴミ箱に移動するにはどうすればよいですか?
2番目の質問(いいえ、数えられません):
アプリケーションの起動時に、処理する無題のドキュメントがある場合とない場合があるため、別のモデルで状態を追跡しようとしています。無題のドキュメントが登場したときに、初期データ(以前に参照した)が存在することはすでにわかりました。私の他のモデルには、入力されたデータの成功フラグ/状態を含むいくつかのメタデータがあります。入力されたデータがすべて配置されて正しい場合、状態はそのように示されます。残念ながら、アプリが既存の無題のドキュメントで起動するときに入力されたデータが読み込まれている間、メタデータクラスは読み込まれません。
コードの粗さを許してください。この時点で、コードを元に戻す前に、コードが希望どおりに機能していることがわかるまで、コードをいじっています。
- (bool) createGameState {
NSEntityDescription* description = [NSEntityDescription entityForName:[GameState name] inManagedObjectContext:[self managedObjectContext]];
NSFetchRequest* req = [[NSFetchRequest alloc] init];
[req setEntity:description];
NSError *error = nil;
NSArray *array = [[self managedObjectContext] executeFetchRequest:req error:&error];
[req release];
req = nil;
GameState* result = nil;
if (array) {
NSUInteger count = [array count];
if (!count) {
// Create the new GameState.
DebugLog(@"Creating GameState");
result = [NSEntityDescription insertNewObjectForEntityForName:[GameState name] inManagedObjectContext:[self managedObjectContext]];
[result setIsLoaded:[NSNumber numberWithBool:NO]];
} else {
if (count > 1) {
NSLog(@"WARNING: Potentially Corrupt Game State. found: %lu", count);
}
result = [array objectAtIndex:0];
if ([result isLoaded]) {
[self variantLoaded];
} else {
// In this case, we have an aborted set-up. Since the game isn't
// playable, just refuse to create the GameState. This will
// force the user to create a new game.
return NO;
}
}
} else {
DebugLog(@"error: %@", error);
}
[game setState:result];
return result;
}
配列は常に存在し、カウントは常にゼロであることに注意してください。いいえ、明示的にsave:
どこにも電話をかけていません。標準の自動保存、または保存を実行するユーザーに依存しています。
編集:
CoreDataEditorアプリをインストールしました。問題はデータの保存ではなく、データの読み込みにあることがわかりました。(注:別の問題により、XMLとして保存するように指示された場合、アプリはバイナリとして保存されます。これにより、多くのヘッドバンギングが発生します。)
私はそれを最も単純なコードに分解しました。これは、配列内のGameStateタイプのすべてのオブジェクトを取得する必要があります。保存されたファイルに適切なタイプのオブジェクトが明らかに存在するにもかかわらず、何も取得しません。
NSManagedObjectContext* moc = [self managedObjectContext];
NSEntityDescription* entity = [NSEntityDescription entityForName:@"GameState" inManagedObjectContext:moc];
NSFetchRequest* req = [[NSFetchRequest alloc] init];
[req setEntity:entity];
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:req error:&error];
配列はnullではありませんが、[array count]
0です。
この時点で、私が見落としているのは単純なことだと思います。
2番目の編集:
-com.apple.CoreData.SQLDebug 5
SQLiteとして追加して保存しました。を呼び出すとexecuteFetchRequest
、デバッグログは生成されません。INSERT INTO ZGAMESTATE
エントリがログに表示されます。executeFetchRequest
バックエンドに渡されていないようです。
3番目の編集(これは燃える):
コアデータを使用して、新しいxcodeプロジェクトを作成しました(他のプロジェクトと同じように)。この1つの関数(必要に応じてスタブ)だけをコピーし、で呼び出しを実行しましたwindowControllerDidLoadNib
。この新しいプロジェクトでは、上記のコードが機能します。