7

ユーザーがエントリを追加できる 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 にオブジェクトが存在します。私が間違っていることに関する提案はありますか?

4

3 に答える 3

4

デイブのアプローチを試みましたが、うまくいきませんでした。私は最終的に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;
}

役立つことを願っています

ゴンソウ

于 2010-03-12T20:27:29.587 に答える
0

それはうまくいくはずです。元に戻すマネージャーを managedObjectContext に正しく割り当てましたか? 正しく行った場合、デフォルトで元に戻す登録が有効になっているので、問題ありません。ここにコアデータに関する良い記事があります。コア データと NSUndoManager に関する優れたチュートリアルがここにあります。それが役立つことを願っています。

于 2012-01-15T17:36:31.400 に答える