Swift使用NSKeyedArchiver進行數據持久化保存的經驗


iOS提供了幾種數據持久化保存的方法,有NSKeyedArchiver,Property List,NSUserDefaults和CoreData。我學習下來,覺得保存應用內的諸如列表,記錄這些東西,用NSKeyedArchiver是比較合適的。

它有些類似於操作系統中將文件壓縮存放,而它是將對象壓縮成一個文件存放在iOS設備的硬盤中。這樣的話即使將應用關閉,下次開啟時也能使用方法從硬盤將數據解壓縮出來,供用戶繼續操作這些數據。

讓對象可被NSKeyedArchiver存儲

如果想要使用NSKeyedArchiver保存系統預設類型的方法,那不用做什么額外的工作,直接調用方法保存即可。而如果要保存自己建立的類,則需要讓類繼承NSObject和協議NSCoding,並補上func encodeWithCoder(aCoder: NSCoder)required init?(coder aDecoder: NSCoder)兩個對象。

例如,我們建立了一個對象Person,有String類型的name和Int類型的overall兩個屬性,那我們可以這么寫上述兩個方法來讓它變得可以用NSKeyedArchiver保存:

func encodeWithCoder(aCoder: NSCoder){
   aCoder.encodeObject(name, forKey: "name")
   aCoder.encodeObject(overall, forKey: "overall")
}

required init?(coder aDecoder: NSCoder) {
   name = aDecoder.decodeObjectForKey("name") as! String
   overall = aDecoder.decodeObjectForKey("overall") as! Int
}

保存

保存時需要輸入路徑和壓縮文件名。但是實際上路徑基本是固定的,因為其他位置幾乎都是不可寫的。文件名包括后綴都可以隨意定義。

let filePath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] + "/person.dat"

NSKeyedArchiver.archiveRootObject(person, toFile: filePath)

讀取

讀取時需要注意的是,讀取出來的對象是作為NSObject類存在的,用戶需要自行轉為正確的類。

let filePath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] + "/person.dat"

if let person : Person = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as? Person{
   //處理
}

我遇到的問題

其實抱怨這個問題就是這篇文章我主要目的。我之前做的demo在模擬器上運行毫無問題,但是插上手機在實機上測試,就保存失敗了!搜索了半天資料,發現stackoverflow上有個人與我遇到了同樣的問題。后來經過調試,原來是我路徑中沒有加"/"。如果不加“/”,就變成了在應用主目錄下生成一個Documentsperson.dat的文件,而不是在Documents文件夾下生成person.dat。在模擬器上,你是可以在任何文件夾下生成文件的,而實機上的權限控制就比較嚴格,Documentsperson.dat就會生成失敗。

也是因為我選擇的參考書並不靠譜(日本人藤田泰介所著的《プロの力が身につく iPhone/iPadアプリケーション開発の教科書》),因為它里面的路徑就沒有加“/”。作者估計模擬器跑通了就這樣寫上去了吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM