標籤:ios 學習
iOS持久化
1.檔案系統
不管是Mac OS X 還是iOS的檔案系統都是建立在UNIX檔案系統基礎之上的。
1.1 沙箱模型
在iOS中,一個App的讀寫權限只局限於自己的沙箱目錄中。
沙箱模型到底有哪些好處呢?
安全:別的App無法修改你的程式或資料
保護隱私:別的App無法讀取你的程式和資料
方便刪除:因為一個App所有產生的內容都在自己的沙箱中,所以刪除App只需要將沙箱刪除就可以徹底刪除程式了
iOS App沙箱中的目錄
- App Bundle ,如xxx.app 其實是一個目錄,裡面有app本身的位元據以及資源檔
- Documents, 存放程式產生的文檔資料
- Library , 下面預設包含下面兩個目錄 Caches Preferences
- tmp, 臨時檔案目錄
如果我們想在程式中擷取上面某個目錄的路徑,應該如何?呢? 下面就講講路徑的擷取, 通過NSPathUtilities.h中的NSSearchPathForDirectoriesInDomains函數,我們便可以擷取我們想要的路 徑。 此函數具體聲明如下:
NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
directory 目錄類型 比如Documents目錄 就是NSDocumentDirectory
domainMask 在iOS的程式中這個取NSUserDomainMask
expandTilde YES,表示將~展開成完整路徑
注意函數返回的類型為數組,在iOS中一般這個數組中只包含一個元素,所以直接取lastObject即可。
1.2 NSFileManager
NSFileManager提供一個類方法獲得一個單例。
- /* Returns the default singleton instance.*/ + (NSFileManager *)defaultManager;
下面羅列了NSFileManager的常用方法
- - (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error;
createIntermediates這個參數一般為YES,表示如果目錄路徑中間的某個目錄不存在則建立之,如果是NO的話,則要保證所建立目錄的父目錄都必須已經存在
- - (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error;
如果目錄為空白,則返回空數組
- - (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)linkItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error; - (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;
更多的可以查看文檔 NSFileManager Class Reference。
在實際項目中,我們一般會寫一個工具類來負責項目中所有的路徑操作。
2. 歸檔(Archives) 和 序列化(Serializations)
我們經常聽到“序列化”,“還原序列化”這樣的字眼,其實“序列化”的意思就是將對象轉換成位元組流以便儲存或傳輸,“還原序列化”便是一個相反的過程,從位元組流轉到對象。
在這節中涉及到一種檔案類型plist,plist就是Property List 的縮寫,即所謂的屬性列表,屬性列表有兩種資料格式,一種是XML的,方便閱讀和編輯;另一種是二進位的,節省儲存空間,以及提高效率。
在Objective-C中這個對象和位元組流的互轉分成兩類:
- 歸檔 普通自訂對象和位元組流之間的轉換
- 序列化 某些特定類型(NSDictionary, NSArray, NSString, NSDate, NSNumber,NSData)的資料和位元組流之間(通常將其儲存為plist檔案)的轉換
不過本質上講上述兩種都是對象圖(Object Graph)和位元組流之間的轉換. Apple關於序列化和歸檔的編程指南: Archives and Serializations Programming Guide 。
2.1 歸檔
如果我們需要將自訂的一個對象儲存到檔案,應該如何做呢?
這裡引入兩個東西:一個是NSCoding協議 ;另一個是NSKeyedArchiver,NSKeyedArchiver其實繼承於NSCoder,可以以鍵值對的方式將對象的屬性進行序列化和還原序列化。
具體的過程可以這樣描述 通過NSKeyedArchiver 可以將實現了NSCoding協議的對象 和 位元組流 相互轉換 。
像一些架構中的資料類型如NSDictionary,NSArray,NSString... 都已經實現了NSCoding協議,所以可以直接對他們進行歸檔操作。
這裡來一個比較完整的例子,一個Address類,一個User類,User類下有個Address類型的屬性。
Address類
User類
使用樣本
通過查看檔案內容可以發現,儲存的是plist的位元據格式。 轉成XML可以看到如下內容:
2.2 序列化
在實際的項目中,我們一般是將NSDictionary或NSArray的對象儲存到檔案或者從檔案讀取成對象。 當然這種只是適用於資料量不是很大的應用情境。 NSDictionary和NSArray 都有一個寫入檔案的方法
NSDictionary和NSArray會直接寫成plist檔案。
2.2.1 序列化的方式
序列化可以通過兩種途徑來進行
使用資料對象內建的方法
寫檔案
寫完的檔案內容如下:
現在 持久化資料用第三方的比較多!
iOS 最佳化記憶體(八)持久化