1

NSManagedObjectContextに関連付けられた組み込みのNSUndoManagerを介した元に戻す/やり直しをサポートするCoreDataドキュメントベースのアプリがあります。Core Data内で多数のタスクを実行し、これらすべてのタスクをbeginUndoGrouping/を介してUNDOグループにラップendUndoGroupingし、NSUndoManagerによって処理されるいくつかのアクションを設定しています。

元に戻すは正常に機能します。いくつかの連続したアクションを実行できます。その後、それぞれを連続して元に戻すと、アプリの状態が正しく維持されます。ただし、「やり直し」メニュー項目は有効になりません。これは、NSUndoManagerがメニューにやり直す項目がないことを通知していることを意味します。

NSUndoManagerが、元に戻されたアイテムを忘れているように見え、REDOの発生を許可していないのはなぜですか?

私が言及しなければならないことの1つは、ドキュメントが開かれた/作成された後に元に戻る登録を無効にしているということです。アクションを実行するときは、、を呼び出し、enableUndoRegistrationアクションを実行してから、、、、を呼び出し、最後に。beginUndoGroupingを呼び出します。これにより、特定のアクションのみが元に戻せるようになり、これら以外で行った他のデータ変更はNSUndoManagerに認識されなくなります。これは問題の一部かもしれませんが、もしそうなら、なぜそれがやり直しに影響を与えているのか疑問に思いますか?processPendingChangessetActionName:endUndoGroupingdisableUndoRegistration

前もって感謝します。

4

3 に答える 3

3

実際、-undoと-redoの両方の前にenableUndoRegistrationを呼び出す(そしてそれらの後にdisableUndoRegistrationを呼び出す)限り、あなたはあなたが求めていたものを達成することができます。

管理対象オブジェクトへの変更の前後に、enable(/ disable)UndoRegistrationのみを呼び出していたと思います。これは、'undo'がundomanagerに登録されていないため、'redo'できなかったことを意味します。

于 2010-05-08T14:21:43.857 に答える
1

私はこの問題を次のように修正しました:

明示的に取り消しを記録したくない場合を除いて、取り消し登録を常に有効にしておく。

私はそれを学びました:

記録したい変更を実行する直前にUNDO登録を有効にし、それらの変更をコミットした直後に無効にした場合、NSUndoManagerのREDOスタックにデータが入力されることはありません。

したがって、決して呼び出さないでdisableUndoRegistrationください。

于 2010-05-08T13:59:05.720 に答える
1

「やり直し」を有効にしたまま、disableUndoManagerを呼び出しました。これを行うために、NSUndoManagerをサブクラス化し、次のメソッドを含めました。

-(void) undo
{
  [[appDelegate managedObjectContext] processPendingChanges];
  [self enableUndoRegistration];
  [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
  [super undo];
  [[appDelegate managedObjectContext] processPendingChanges];
  [self disableUndoRegistration];
}

NSUndoManager、Core Data、および選択的な元に戻す/やり直しでStefanfが述べているように、「NSUndoManagerは、変更が登録されるまで、次の実行ループサイクルを待機します」

于 2014-06-04T04:58:14.993 に答える