2017-05-21 34 views
3

我知道UserDefaults只是爲了保存偏好,但這些偏好是持久的 - 保存在UserDefaults中的值是通過無限數量的應用程序啓動維護的,只要應用程序保持安裝狀態,就可以隨時讀取它們。對?UserDefaults.standard值可能無法讀取嗎?

這些值可能會被清除,或者在任何時候都無法正確訪問嗎?經過多年使用UserDefaults並根據它們所保持的值的一致性,我現在在工作的一天中看到過兩次,當我的應用程序啓動並檢查了一個簡單的布爾值時,該值不正確。

if defaults.bool(forKey: "beenLaunched") { 

每次啓動應用程序時都會運行此代碼。如果這個值是真的,我什麼也不做,但如果它是假的,我設置一些值,因爲這是用戶第一次啓動應用程序,然後我調用defaults.set(true,forKey:「beenLaunched」)和defaults.set(0,forKey:「eventsCompleted」)和其他一些值。

我發現this thread on the Apple forums其中Eskimo說:「對於中央的NSUserDefaults方法,-objectForKey:,nil的結果意味着該值不可用,但是沒有辦法區分這個鍵不存在,並且此值可以'因爲用戶的默認值是離線的,所以不會被提取。「 (這似乎是參考background launching while a device is locked的具體情況)

我可以考慮一種更安全的方式來保存諸如Bool值,Int或String之類的簡單數據,但使用UserDefaults來處理這些類型的價值觀一直是簡單,直接和可靠的。任何人都可以在這件事上留言,如果我錯誤地相信UserDefaults的持久性?

謝謝!

+1

在設置值之後是否調用了'NSUserDefaults :: synchronize()'? – Brandon

+2

17年來一直使用Cocoa框架,這不是它的工作原理。 :-)沒有麻煩閱讀該線程,但沒有,它永遠不會「脫機」(甚至不知道這是什麼意思*)。 –

+2

@Brandon不,我通常不會同步,但從來沒有問題 – RanLearns

回答

3

UserDefaults不是「服務」;它永遠不可用於您的應用程序。它寫入的文件是一個PLIST(因此所有值都根據PLIST標準存儲)。例如,所有數字(包括布爾值)都以文件NSNumber的形式存儲,並且可以通過object(forKey:)bool(forKey:)檢索。如果使用對象方法,並且沒有爲該值設置任何值,則獲得nil,其布爾值爲false(或0)。如果你使用布爾方法(你會得到false)。這意味着無論你走哪條路,如果沒有價值或價值false,你總是會失敗。設計你的邏輯(你已經有了 - "beenLaunched"將是空的,因此false如果它從未啓動),你應該沒問題。

至於synchronize()的建議,請忽略它。除非你使用線程和首選項訪問來做一些非常奇怪的事情,或者在設置問題關鍵字的值/對象後立即中斷應用程序,這與此無關。根據文檔的第一段,根據需要定期調用synchronize()。實際上,發生更改後立即調用它。

對於上下文,我的應用程序都沒有稱爲synchronize(),其中一些應用程序已經夠大了。從來沒有一個問題。如果你沒有非常好的理由自己撥打synchronize()你幾乎肯定不需要它,並試圖解釋爲什麼你需要撒在任何地方都經常有趣。

在您的具體情況下,第一次運行多次後卡住的值突然沒有發生。是否可以更改應用程序的包標識符或名稱?默認值是通過標識符+名稱存儲的,所以更改會有效地「重置」您應用程序的默認值。你是否已經在模擬器中運行你的應用程序,並且只是在模擬器中重置內容和設置?在您的設備上重新運行設備之前刪除了該應用程序?

+0

感謝@JoshuaNozzi的解釋和備份,不需要手動調用同步(),但我確信他們不會受到傷害。我沒有更改標識符/名稱,但很好指出。我在具有各種設備外觀的模擬器以及實際設備上快速連續測試該應用程序。我不知道是什麼造成了這個問題,但我無法複製這個問題(儘管它發生了兩次),我不想懷疑我所知道的一直是保存到PLIST文件的可靠方法。 – RanLearns

+0

自從Swift引入了bool(forKey :),integer(forKey :)和string(forKey :)之後,我已經試過使用那些特定的對象(forKey :),當變量類型是明確的 – RanLearns

-1

如果您在swift中工作,則返回nil意味着objectforkey尚未分配任何值。在其他情況下,如果您正確存儲了保存的值,它將始終返回適當的值。

並且userdefaults始終可以使用,它永遠不會脫機。