所謂固化
固化就是iOS SDK提供的一種保存和讀取對象的機制
具體使用
要使用固化功能,需要遵守<NSCoding>協議,并且實現兩個方法:
- (void)encodeWithCoder:(NSCoder *)aCoder; //對數據進行編碼
- (instancetype)initWithCoder:(NSCoder *)aDecoder; //還原上面的編碼
創建一個Model類,有如下屬性:
@interface model : NSObject
@property (nonatomic, copy) NSString * name;
@property (nonatomic, copy) NSString * detail;
@property (nonatomic, assign) NSInteger ID;
@end
將Model遵守<NSCoding>協議,實現上面所說的方法:
- (void)encodeWithCoder:(NSCoder *)aCoder {
//將各個屬性編碼,以便保存
// 如果屬性是對象類型(NSString)的就用 encodeObject:forKey 方法來編碼
//如果屬性是基礎類型(NSInteger)的就用 encodeInteger:forKey 方法來編碼
//具體用哪一個方法來編碼,可以進入NSCoder對象中查看
[aCoder encodeObject:self.name forKey:@"modelName"];
[aCoder encodeObject:self.detail forKey:@"modelDetail"];
[aCoder encodeInteger:self.ID forKey:@"modelID"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
//對數據進行解碼
_name = [aDecoder decodeObjectForKey:@"modelName"];
_detail = [aDecoder decodeObjectForKey:@"modelDetail"];
_ID = [aDecoder decodeIntegerForKey:@"modelID"];
}
return self;
}
獲取文件路徑
每個iOS應用都有自己專屬的沙盒,沙盒就是所謂的文件系統中的目錄,但是iOS系統會將每個應用的沙盒目錄與文件系統的其他部分進行隔離,應用只能訪問自己的沙盒。
沙盒中包含以下幾個目錄:
應用程序包 : 包含應用可執行文件和所有資源文件,例如NIB文件和圖像文件,它是只讀目錄
Documents/ : 存放應用運行時聲稱的并且需要保留的數據,iTunes或iCloud會在同步設備時備份該目錄
Library/ (這個目錄下有兩個目錄,分別是:Caches和Preferences):
Library/Caches/ : 存放應用運行時聲稱的需要保留的數據,但是iTunes或iCloud不會再同步設備時備份該目錄,就是所謂的緩存區
Library/Preferences/ : 存放所有的偏好設置,iTunes或iCloud會在同步設備時備份該目錄
tmp/ : 存放應用運行時所需的臨時數據,iTunes或iCloud不會再同步設備時備份該目,通過NSTemporaryDirectory函數可以得到該目錄
創建一個Store類來對Model對象進行操作
@interface Store()
//創建一個數組來保存多個Model對象
@property (nonatomic, copy) NSMutableArray * items;
@end
獲取文件路徑的方法:
在Store類中實現下面的方法
- (NSString *)itemArchivePath {
//注意第一個參數是NSDocumentDirectory而不是NSDocumentationDirectory
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//從documentDirectories數組獲取第一個,也是唯一文檔目錄路徑
NSString *documentDirectory = [documentDirectories firstObject];
//下面的參數是作為文件的名字,可以自由更改,這里以saveData.archive為例
return [documentDirectory stringByAppendingPathComponent:@"saveData.archive"];
}
上面的方法就在應用程序的沙盒中的Documents/ 目錄下創建了一個叫saveData.archive的文件,并返回改文件的路徑。NSSearchPathForDirectoriesInDomains方法中的第一個參數為NSSearchPathDirectory類型,不同類型能夠獲取不同目錄,而后兩個參數是固定的。
將數據保存到文件中
通過NSKeyedArchiver的archiveRootObject:方法來實現保存
通過NSKeyedUnarchiver的unarchiveObjectWithFile:方法來讀取數據
在Store類中實現下面的方法:
//保存的方法
- (BOOL)saveChages {
//首先獲取保存的路徑
NSString *path = [self itemArchivePath];
return [NSKeyedArchiver archiveRootObject:self.items toFile:path];
}
- archiveRootObject:方法會向_items發送encodeWithCoder:消息,并傳入NSKeyedArchiver對象作為第一個參數。
- _items的encodeWithCoder:方法會向其包含的所有Model對象發送encodeWithCoder:消息,并傳入NSKeyedArchiver對象,這些Model對象都會將其屬性編碼至同一個NSKeyedArchiver對象。
- 當所有對象都完成編碼后,NSKeyedArchiver對象就會將數據寫入指定的文件。
(PS:這就是上面再Model類中實現 encodeWithCoder:方法的原因)
//讀取的方法
- (void)readData {
NSString *path = [self itemArchivePath];
_items = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
}
- unarchiveObjectWithFile:方法會創建一個NSKeyedUnarchiver對象,然后根據指定的路徑載入固化文件。接著,NSKeyedUnarchiver類會查看固化文件中的根對象,然后根據對象的類型創建相應的對象。這里創建的時候使用的是NSMutableArray對象,所以解固時的根對象也是NSMutableArray(如果根對象是NSString對象,那么unarchiveObjectWithFile:也會返回NSString對象)。
- 上面創建說道的創建好的NSKeyedUnarchiver對象的unarchiveObjectWithFile:方法會向新創建的NSMutableArray對象(_items)發送initWithCoder:消息,并將NSKeyedUnarchiver對象作為實參傳入。
- NSMutableArray對象會通過NSKeyedUnarchiver對象解碼相關的對象(Model對象),向所有解固后的對象發送initWithCoder:消息,傳入同一個NSKeyedUnarchiver對象。
(PS:這就是上面再Model類中實現 initWithCoder:方法的原因)