2

にトランザクション性を追加する方法はありますNSUserDefaultsか? データベース ハンドラーでよく知られている begin - commit - revert 関数のようなものが必要になるため、場合によってはユーザーのデフォルトの変更を元に戻すことができます。もちろん、このユーザー デフォルトの他のユーザーは、トランザクション中に書き込みをブロックされます。

注 1:synchronize上記のクラスのメソッドは、次の理由でこのことを行いません。

  1. ドキュメントによると、フレームワークによっても時々呼び出されます
  2. 「元に戻す」はありません

注 2: 私は自分自身のトランザクション メカニズムを実装できることを確認しました (古いデフォルトのコピーをメモリに保持し、トランザクション中に plist に保存することもできます) dictionaryRepresentationregisterDefaultsしかし、おそらくこれに対する解決策はありますか?

私のユースケース:

ユーザーが各画面でいくつかの設定を編集できるウィザードのような画面フローがあります。現在の実装では、これらの設定は、ユーザーがウィザードの次の画面に移動するとすぐにデフォルトに保存されます。現在、このウィザードは他のイベントによって中断される可能性があります (ユーザーは任意の画面でウィザードを終了/キャンセルすることもできます)。この場合、変更をロールバックしたいと思います。

4

1 に答える 1

3

考えられる解決策の1つは、ウィザードが終了するまで値の設定を延期することです。これは、たとえば、送信されたメッセージを記録してから実際に再生するプロキシを使用して簡単に実行できますNSUserDefaults。メッセージの録音は非常に簡単です。

- (void) forwardInvocation: (NSInvocation*) invocation
{
    [invocations addObject:invocation];
}

invocations可変配列はどこにありますか。メッセージの再生も簡単です。

- (void) replayOnTarget: (id) target
{
    for (NSInvocation *op in invocations)
        [op invokeWithTarget:target];
}

このように、ウィザードはトランザクションについて何も知る必要がありません。予期されたインスタンスの代わりにレコーディングプロキシを取得し、NSUserDefaults通常どおりメッセージを送信します。呼び出し元のコードは、ウィザードが成功したことを認識した後、共有ユーザーのデフォルトでプロキシからのメッセージを再生できます。( GitHubにサンプルコードを追加しました。)

これはやり過ぎかもしれませんが、レコーディングプロキシは一般的であり、他の場合にも使用できるため、悪くないかもしれません。ブロックを使用して同じことを行うこともできます。

[transaction addObject:[^{
    [defaults setObject:… forKey:…];
} copy]];

transaction繰り返しますが、可変配列はどこにありますか。ウィザードが成功すると、配列を繰り返し処理して、保存されているブロックを実行するだけです。

于 2012-05-24T15:43:50.113 に答える