ユーザーがエントリを追加できる iPhone アプリケーションを作成しようとしています。彼が新しいエントリを押すと、いくつかの情報を求めるボックスがポップアップします。次に、[キャンセル] または [保存] を押してデータを破棄するか、ディスクに保存します。
保存には、かなりうまく機能する Core Data フレームワークを使用しています。ただし、「キャンセル」ボタンが機能しません。情報を求めるウィンドウが表示されたら、マネージド オブジェクト コンテキスト (MOC) に新しいオブジェクトを作成します。次に、ユーザーがキャンセルを押すと、MOC に属する NSUndoManager を使用しようとします。
また、ネストされたグループがある可能性があるため、ネストされた元に戻すグループを使用して実行したいと思います。
これをテストするために、簡単なアプリケーションを作成しました。アプリケーションは、Core Data が有効になっている単なる「ウィンドウ ベースのアプリケーション」テンプレートです。Core Data モデルの場合、整数属性 "x" を持つ "Entity" という単一のエンティティを作成します。次に、applicationDidFinishLaunching 内に、次のコードを追加します。
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
unsigned int x=arc4random()%1000;
[self.managedObjectContext processPendingChanges];
[self.managedObjectContext.undoManager beginUndoGrouping];
NSManagedObject *entity=[NSEntityDescription insertNewObjectForEntityForName:@"Entity"
inManagedObjectContext:self.managedObjectContext];
[entity setValue:[NSNumber numberWithInt:x] forKey:@"x"];
NSLog(@"Insert Value %d",x);
[self.managedObjectContext processPendingChanges];
[self.managedObjectContext.undoManager endUndoGrouping];
[self.managedObjectContext.undoManager undoNestedGroup];
NSFetchRequest *fetchRequest=[[NSFetchRequest alloc] init];
NSEntityDescription *entityEntity=[NSEntityDescription entityForName:@"Entity"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entityEntity];
NSArray *result=[self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
for(entity in result) {
NSLog(@"FETCHED ENTITY %d",[[entity valueForKey:@"x"] intValue]);
}
[window makeKeyAndVisible];
}
考え方は単純です。新しい Entity オブジェクトを挿入して元に戻し、MOC 内のすべての Entity オブジェクトを取得して出力してみてください。すべてが正常に機能した場合、最後にオブジェクトは存在しないはずです。
ただし、次の出力が得られます。
[Session started at 2010-02-20 13:41:49 -0800.]
2010-02-20 13:41:51.695 Untitledundotes[7373:20b] Insert Value 136
2010-02-20 13:41:51.715 Untitledundotes[7373:20b] FETCHED ENTITY 136
ご覧のとおり、オブジェクトの作成を元に戻そうとすると、MOC にオブジェクトが存在します。私が間違っていることに関する提案はありますか?