2012-05-24 44 views
1

有什麼辦法可以將事務添加到NSUserDefaults?我需要類似數據庫處理程序中衆所周知的begin - commit - revert函數,因此我可以在某些情況下恢復對用戶默認值的修改。當然這個用戶默認的其他用戶會在交易過程中被阻止寫入。NSUserDefaults事務性

注1:上述類的synchronize方法因爲不做這件事情:根據文檔

  1. ,它是從時間調用時間也由框架
  2. 沒有「恢復」

注2:我看到dictionaryRepresentationregisterDefaults用,我可以實現我自己的交易機制(持有舊默認的拷貝在內存/甚至可以保存d交易期間交給plist)。但也許有一個現成的解決方案呢?

我的使用情況:

我的屏幕,用戶可以在每個屏幕上編輯一些設置的精靈般流。在當前實施中,隨着用戶移動到嚮導的下一個屏幕,這些設置會立即存儲在默認值中。現在這個嚮導可以被一些其他事件中斷(即使用戶可以選擇在任何屏幕上退出/取消嚮導),在這種情況下,我想回滾修改。

+1

你的用例是什麼? – zoul

+0

在github中有一個[StateSaver類](https://github.com/progrmr/SDK_Utilities/blob/master/Utils/StateSaver.h),幾乎可以滿足你的需求。 -saveDataToFile方法在功能上等同於提交。它沒有恢復,但是如果你想修改它,則提供源。 – progrmr

+0

@zoul我有一個類似嚮導的流程,用戶可以在每個屏幕上編輯一些設置。在當前實施中,隨着用戶移動到嚮導的下一個屏幕,這些設置會立即存儲在默認值中。現在這個嚮導可以被一些其他事件中斷(即使用戶可以選擇在任何屏幕上退出/取消嚮導),在這種情況下,我想回滾修改。 – MrTJ

回答

3

一種可能的解決方案是推遲設置值直到嚮導結束。這可以很容易地完成,例如使用代理來記錄發送給它的消息,然後在真實的NSUserDefaults上重播它們。錄製這些消息應該很簡單:

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

其中invocations是一個可變數組。重播消息也很簡單:

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

這樣,嚮導不必知道有關事務的任何信息。它將獲得錄製代理而不是預期的NSUserDefaults實例,並照常發送消息。在調用代碼知道嚮導成功之後,它可以在共享用戶默認值上重播來自代理的消息。 (我增加了一些sample code on GitHub

也許這就是矯枉過正,但由於記錄代理是通用的,可以在其他情況下被使用,也許這是不壞。同樣的事情也可以用做塊:

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

transaction是一個可變數組,再次。當嚮導成功時,您只需遍歷數組並執行存儲的塊。

+0

非常感謝,我從你的回答中學到了很多東西。 – MrTJ

+0

...高興地幫忙! – zoul