2

iPadアプリケーション(OpenGL描画アプリ)にやや複雑なデータモデルがあり、元に戻す/やり直し機能の実装に取り​​組んでいます。Core Dataがデータモデルの変更を無料で元に戻すという事実は気に入っていますが、組み込みの機能で十分かどうかはわかりません。

描画アプリに元にされる/やり直しが実装されている例をたくさん見てきましたが、それらは一般的に次のことを行います。

  1. 管理対象オブジェクトのコンテキストをに伝えますundo
  2. 変更したデータモデルからページ上のすべてを再描画します。

これはひどく非効率的です-私のアプリでは、「元に戻されている」特定のオブジェクトに基づいて元に戻すアクションを実行できる必要があります。これは、多くの場合、キャンバスの一部のみを更新することを意味します。

だから私の質問はこれです:私は自分の取り消し操作を登録し、それを組み込みの取り消しと組み合わせて使用​​できますか?たとえば、ユーザーが線を引いたときに次のようにするとします。

- (void)drawLineFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint
{
    // Register the undo operation.
    [[[managedObjectContext undoManager] prepareWithInvocationTarget:self] 
                                               removeObjectWithIndex:nextObjectIndex];

    // Draw the line object.  
    [self drawLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];

    // Save the new object to the data model.
    [MyCoreDataHelper saveLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];

    nextObjectIndex++;
}

このアクションを元に戻すと、呼び出しが実行れ、モデルが適切に変更されますか?NSUndoManagerまたは、この状況では、組み込みの管理対象オブジェクトコンテキスト取り消しシステムを放棄し、データモデルを自分で削除および編集するなど、を使用して自分自身をロールバックする必要がありますか?組み込みの元に戻る/やり直しが実際に何を元に戻すのかわからない限り、これはひどく厄介で複雑になる可能性があるようです...

編集:(上記のアイデアが機能する場合)登録された元に戻す操作がデータモデルの変更とともにグループ化されるように、それを元に戻すグループにラップする必要があると思いますか?

別の編集:また、元に戻すアクションが実行される順序を保証できますか?つまり、undoコアデータの変更が保存され、元に戻すアクションが登録された後に呼び出す場合、元にされるアクションが呼び出される前に、削除されたエンティティが復元されることを確認できますか?

4

2 に答える 2

2

それでは、元に戻すから変更されたデータを特定できるかどうかを知っていますか?

(Apple Docs)の通知をチェックしてみませんかNSManagedObjectContext

具体的には、キー、、、およびを使用して通知のuserInfoを確認しますNSInsertedObjectsKeyNSUpdatedObjectsKeyNSDeletedObjectsKey

また、元に戻すアクションが実行される順序を保証できますか?

ええと、元に戻るはスタック(後入れ先出し)を介して機能するので、「ステップを追跡できるはずです」。明らかに、物事を正しく展開したい場合は、取り消しを登録する順序を非常に具体的にする必要があります。謎のベールの背後にあるものを確認するためだけにUNDOスタックをトレースするのに役立つ数行のコード:

id undoStack, redoStack;
object_getInstanceVariable(undoManager, "_undoStack", &undoStack);
object_getInstanceVariable(undoManager, "_redoStack", &redoStack);
NSLog(@"%@", [undoStack description]);
NSLog(@"%@", [redoStack description]);

(上記のコードのこのサイトへの小道具)

于 2012-01-26T01:47:00.770 に答える
0

構造を使用してくださいflyweight通常、元に戻す/やり直し操作に使用されます。あなたが求めていることは、これを自分で行う必要があります。

フライウェイトは必要なだけデータを保存でき、いつでも元に戻すシーケンスから削除できます。たとえば、フライウェイトは、各編集が行われる前にピクセル データを保存できます。これには大量のメモリが必要ですが、シーン全体を再描画しなくても簡単に元に戻すことができます。

于 2012-01-27T04:13:28.117 に答える