NSUndoManagerアンドゥが動作しないとコアデータ
-
21-09-2019 - |
質問
私は、ユーザーがエントリを追加できるiPhoneアプリケーションを作成しようとしています。彼は新しいエントリを押すと、ボックスにはいくつかの情報のために彼を尋ねるポップアップします。それから彼ができ押すか、データを破棄するか、ディスクに保存するために「キャンセル」または「保存」ます。
節約のために、私はかなりうまく機能コアデータフレームワークを、使用しています。しかし、私は仕事に「キャンセル」ボタンを取得することはできません。ウィンドウが情報を求めて、ポップアップしたとき、私は、管理対象オブジェクトコンテキスト(MOC)で新しいオブジェクトを作成します。ユーザーを押すキャンセルする場合次に、私がMOCに属するNSUndoManagerを使用するようにしてくださいます。
私はまた、ネストされたグループがあるかもしれませんので、ネストされたアンドゥ・グループを使用してそれを実行したいと思います。
はこれをテストするために、私は簡単なアプリケーションを書きました。アプリケーションは、コアデータを有効にして、単に「ウィンドウベースのアプリケーション」テンプレートです。コアデータモデルのために、私は整数属性「X」と「エンティティ」と呼ばれる単一のエンティティを作成します。その後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];
}
アイデアは単純です。すべてのエンティティは、MOCにオブジェクトをフェッチし、それらをプリントアウトし、それを元に戻す、新しいエンティティオブジェクトを挿入するようにしてください。すべてが正常に働いていた場合は、最後に何のオブジェクトがあってはならない。
しかし、私はこの出力を取得します:
[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に存在しています。 私が間違ってやっているものになど任意の提案ですか?
解決
はあなたの問題は、OS Xとは異なり、iPhoneはデフォルトでアンドゥマネージャが含まれていないオブジェクトコンテキストを管理し、事実によって引き起こされます。あなたは明示的に追加する必要があります。
変更このように見えるようにmanagedObjectContextプロパティのアプリデリゲートで生成されたコード:
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
//add the following 3 lines of code
NSUndoManager *undoManager = [[NSUndoManager alloc] init];
[managedObjectContext setUndoManager:undoManager];
[undoManager release];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
その変更を行った後、2番目のログメッセージは、もはや印刷されない。
... 助け希望
デーブ
他のヒント
私はデイブのアプローチを試みたが、私のために動作しませんでした。 私は最終的にAppleの例 CoreDataBooksする
トリックは、あなたのアプリケーションのコンテキストでコーディネーターを共有する新しいコンテキストを作成することです。あなたが事を行う必要がいけない変更を破棄するには、単に新しいコンテキストオブジェクトを破棄します。あなたがコーディネーターを共有しているため、更新のメインのコンテキストを保存します。
ここで私は一時コンテキストの静的オブジェクトを使用して、私の適応バージョンは、新しいChannelMOオブジェクトを作成することです。
//Gets a new ChannelMO that is part of the addingManagedContext
+(ChannelMO*) getNewChannelMO{
// Create a new managed object context for the new channel -- set its persistent store coordinator to the same as that from the fetched results controller's context.
NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init];
addingManagedObjectContext = addingContext;
[addingManagedObjectContext setPersistentStoreCoordinator:[[self getContext] persistentStoreCoordinator]];
ChannelMO* aux = (ChannelMO *)[NSEntityDescription insertNewObjectForEntityForName:@"ChannelMO" inManagedObjectContext:addingManagedObjectContext];
return aux;
}
+(void) saveAddingContext{
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
[dnc addObserver:self selector:@selector(addControllerContextDidSave:)
name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];
NSError *error;
if (![addingManagedObjectContext save:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];
// Release the adding managed object context.
addingManagedObjectContext = nil;
}
私はそれが
役に立てば幸いGonso