2011-04-02 54 views
23

我不知道什麼的指導方針是:
1 - 我怎麼可以經常從NSUserDefaults的閱讀
2 - 有多少數據,我可以在NSUserDefaults的當(不是)濫用NSUserDefaults的

合理的存儲

顯然,有限制可以使用多少NSUserDefaults,但我無法確定什麼是合理的,什麼是不合理的。

在其他一些例子:

  • 如果我的比賽有計算機是一個玩家的選擇,我會使用到NSUserDefaults的保存布爾值。這很清楚。但是每次我想知道計算機是玩家還是應該使用實例變量時,在我的遊戲中訪問NSUserDefaults是否也合理?假設我需要每秒鐘檢查布爾值。答案是一樣的,而不是100毫秒?大概每10秒鐘一次?

  • 如果我的遊戲有50個移動對象,並且我希望在用戶退出應用程序時存儲他們的位置和速度,NSUserDefaults是否存儲這些數據的合理位置?關於20個移動物體呢?什麼約200?

回答

13

不要擔心限制。相反,問自己這個簡單的問題:

這是偏好嗎?

如果是首選項,那麼它應該是用戶默認值。這就是用戶默認的用途。如果不是,那麼它應該位於文檔目錄中(或者在Mac上,可能在應用程序支持中)。

在iOS上,您可能會根據是否適合(如果可能)將其放入設置包中以便在「設置」應用程序中進行顯示和編輯,來判斷它是否爲首選項。在Mac OS X上,通常可以通過將它放在「首選項」窗口中來判斷是否是首選項。

當然,這依賴於你的判斷。例如,Mac版的Stanza錯誤地將非偏好設置放在其「首選項」窗口中。

您還可以通過它的逆考慮的問題是:

這是用戶創建的數據嗎?

您將擁有默認值的首選項不是用戶創建的數據;它是用戶被覆蓋的數據。失去它不會不好,但它會告訴你應該保留它的位置。

+0

感謝所有的答覆。這有所幫助。 – double07 2011-04-02 16:53:41

7

成百上千的項目在NSUserDefaults中很好(它基本上只是屬性列表序列化的一個包裝)。關於你的應用程序的開銷,最好的辦法是嘗試它並使用一個分析器。

+2

謝謝你提到使用探查器。你是我的英雄。 – 2012-10-07 18:17:59

16

我不知道準則是什麼: 1 - 如何,我經常能NSUserDefaults的從

相當經常閱讀。預期違約的開銷是類似一個線程安全的NSDictionary

2 - 有多少數據,我可以在NSUserDefaults的

合理的存儲

身體,比你更需要它。邏輯最大值是您需要多快以及磁盤佔用多少空間。還要記住,在啓動/關閉以及其他各種時間,都會將此表示形式讀寫到磁盤。

如果我的遊戲有一個選項讓電腦成爲其中一名玩家,我將使用NSUserDefaults來保存該布爾值。這很清楚。但是每次我想知道計算機是玩家還是應該使用實例變量時,在我的遊戲中訪問NSUserDefaults是否也合理?

只需將一個const bool添加到對手對象。零運行時間的損失,除了內存之外,哪個不會很大。

假設我需要檢查每秒布爾值。答案是一樣的,而不是100毫秒?大概每10秒鐘一次?

再次,它就像一個線程安全的NSDictionary(哈希)。它將會相當快,並且足夠快以便在該頻率下閱讀。它是否是最好的設計取決於程序。如果它變得巨大,那麼表現會受損。

如果我的比賽有50米移動的物體,我希望自己的位置和速度,當用戶退出應用程序存儲,NSUserDefaults的是存儲數據在合理的地方?關於20個移動物體呢?什麼約200?

it would很好,雖然我不會在玩遊戲時通過用戶默認值讀/寫;只需根據需要保存/加載狀態即可。

我不建議將所有這些保存在用戶默認值中。只需爲您的遊戲狀態創建一個文件表示形式,並使用用戶默認設置來設計它。如果它很大並且經常寫入,那麼實現可能會定期將狀態刷新到磁盤,這可能需要相當長的時間。

+0

關於您的最後一段,每1到5次刷新一次磁盤到狀態變化,或者使用計時器每分鐘執行一次。 – 2012-10-06 15:08:16

10

這裏沒有人提到的主要性能問題是用戶的主目錄可能位於網絡捲上,可能不是特別快。這不是一個理想的情況,但是它會發生,所以如果你擔心應該測試的性能。

也就是說,NSUserDefaults使用內存中緩存,並且成本只在同步時發生。根據文件,同步「自動......定期發生」;不過,我相信這隻適用於有變化的情況。

因此,對於檢查計算機是否爲播放器的情況,一旦使用NSUserDefaults即可,因爲它被緩存了,所以一個幀不應該成爲問題。爲了存儲遊戲狀態,如果你經常更新遊戲狀態,這可能是一個性能問題,正如Peter Hosey所說,這是一個語義濫用。

2

NSUserDefaults基本上是一個用於從磁盤中加載.plist文件中的NSDictionary(並將其寫入磁盤)的包裝器。您可以將盡可能多的數據存儲在NSUserDefaults中,但您幾乎無法控制它使用多少內存,以及它如何從磁盤讀取數據。

我會對不同的信息/數據使用不同的技術。

  • 從服務器,首選項,用戶信息等等的小數據我會使用NSUserDefaults。

  • 對於登錄信息(訪問令牌,敏感數據),我會使用鑰匙串。鑰匙串也可用於刪除應用程序時不應刪除的數據。

  • 對於大量的服務器數據或遊戲數據,我會將它寫入磁盤,但將其保存在內存中。

在你的情況,我會保持它在內存中(可能是一個@property),但我會定期將其寫入磁盤(也許每1至5倍它的變化,使用int伊娃)。確保此磁盤寫入方法位於AppDelegate中,以便在關閉正在執行它的視圖控制器時它不會失敗。

這樣,數據很容易被訪問,但它也保存到磁盤以保證安全。