2015-05-26 54 views
2

我將我的一個項目從Objective-C轉換爲Swift,並且遇到了一個奇怪的障礙。考慮下面的代碼(在-applicationDidFinishLaunching執行)...NSUserDefaults Plist創建在Swift中失敗(但不是Objective-C)

Objective-C的

請原諒雜亂的一行

[[NSUserDefaults standardUserDefaults] registerDefaults: 
    [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Defaults" ofType:@"plist"]]]; 

在我的Objective-C本項目工程如預期。如果我第一次運行我的應用程序並且沒有plist存在,則在下一次同步調用期間將默認值註冊並保存到新的plist中。如果plist已經存在但缺少一個值,它會從默認值中添加該值。說得通。

斯威夫特

let defaults = NSUserDefaults.standardUserDefaults() 
let plist = NSBundle.mainBundle().pathForResource("Defaults", ofType: "plist") 
defaults.registerDefaults(NSDictionary(contentsOfFile: plist!) as! [NSObject : AnyObject]) 
defaults.synchronize() 

在我的雨燕獨家項目,默認結婚登記入內存,但在-synchronize叫他們從來沒有寫入磁盤。我可以測試並驗證存在於內存中的默認值,如果我登錄的值以上代碼執行後,立即...

println(defaults.objectForKey("showUnread")) 

但值永遠不會保存到plist中。即使我從界面更新了我的一個綁定(所有這些都保存並保持完好),缺省值不會保存爲缺失值。事實上,除非我更新我的一個綁定,否則決不會爲我的應用程序創建一個plist。

然而我的Objective-C項目幾乎是我的Swift項目的逐字翻譯,完美地工作。我必須忽略一些簡單的東西,但是我在Google和Stack Overflow上的搜索已經空了。

故障排除步驟

  1. 創建一個新雨燕的項目,複製Defaults.plist到項目,並把上面的代碼中-applicationDidFinishLoading。完全相同的結果。
  2. 刪除應用程序緩存和plist,清空垃圾並重新啓動。
  3. 我聽說cfprefsd進程可能會保留一個指向已刪除文件的鏈接,但它可以與Objective-C代碼使用相同的包標識符正常工作。

回答

2

registerDefaults的調用永不會持續任何數據(使用任何一種語言)。查找不存在的值時,它只是一個回退。您對數據應寫入磁盤的期望不正確。

您致電synchronize不會做任何事情,因爲您尚未在NSUserDefaults中設置任何值。

+0

我確實知道'registerDefaults'沒有寫入磁盤,但我一直認爲它的目的是創建這些值,如果它們不存在。如果'synchronize'沒有向你的plist提交默認值,'registerDefaults'的用途是什麼?那麼爲什麼Objective-C中的代碼將這些值保存到plist? – Stef

+0

1)Objective-C代碼不保存註冊爲默認值的值。如果您的數據持久存在,則來自其他代碼。2)'registerDefaults'的目的是提供一個內存的一組值,如果一個給定的鍵還沒有保存一個真實值。 – rmaddy

+0

我在回答評論後多想了解你的答案,並意識到我問了你已經回答的一堆問題。所以我想我剩下的唯一剩下的問題是在應用程序第一次啓動時填充「NSUserDefaults」的標準做法是什麼?檢查零和'setObject'? – Stef