歸檔與反歸檔
- 複雜物件就是在Foundation框架內不存在的資料類,例如我們自定義的Person類。
- 複雜物件無法通過writeToFile:的方法進行資料持久化,只能通過將複雜物件轉化為NSData(這個步驟就是歸檔),然後在通過writeToFile:寫入檔案。
- 複雜物件寫入檔案的過程(讀取檔案->歸檔->NSData->writeToFile)。
- 從檔案中讀取NSData資料,然後將NSData轉換為複雜物件(這個步驟就是反歸檔)
- 從檔案中讀取複雜物件的過程(讀取檔案->NSData->反歸檔->複雜物件)
準備工作
首先複雜物件所屬的類要遵守協議。然後再實現協議中的兩個方法
- 歸檔(序列化)時呼叫的方法
-(void)encodeWithCoder:(NSCoder *)aCoder;
複製程式碼
- 反歸檔(反序列化)時呼叫的方法
-(nullable instancetype)initWithCoder:(NSCoder *)aDecoder;
複製程式碼
- 遵守NSCoding協議
@interface Archiver : NSObject<NSCoding>
@property (strong, nonatomic)NSString *name;
@property (assign, nonatomic)NSInteger age;
@property (strong, nonatomic)NSString *address;
@property (strong, nonatomic)UIImage *photo;
@end
複製程式碼
- 實現協議中的兩個方法
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
[aCoder encodeObject:self.address forKey:@"address"];
[aCoder encodeObject:self.photo forKey:@"photo"];
}
複製程式碼
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
self.address = [aDecoder decodeObjectForKey:@"address"];
self.photo = [aDecoder decodeObjectForKey:@"photo"];
}return self;
}
複製程式碼
- 注意:在對物件進行歸檔和犯規當的時候,我們需要針對不同資料型別,採用與之相匹配的歸檔和反歸檔的方法,才能夠成功的進行歸檔與反歸檔。
- 獲取檔案路徑的方法
-(NSString *)GetThefilePath:(NSString *)filePath{
NSString *Path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES)firstObject]stringByAppendingPathComponent:filePath];
return Path;
}
複製程式碼
同時對多個物件進行歸檔
歸檔
- 準備資料
CGPoint point = CGPointMake(1.0, 2.0);
NSString *info = @"座標原點";
NSInteger value = 10;
複製程式碼
- 獲取要儲存的檔案路徑
NSString *multiHome = [self GetThefilePath:@"multi.archiver"];
複製程式碼
- 準備一個NSMutableData,用於儲存歸檔後的物件
NSMutableData *data = [[NSMutableData alloc] init];
複製程式碼
- 建立歸檔工具
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
複製程式碼
- 進行歸檔 歸檔的時候,是根據鍵-值對應的關係將物件轉換為NSData型別的資料。
[archiver encodeCGPoint:point forKey:@"kPoint"];
[archiver encodeObject:info forKey:@"kInfo"];
[archiver encodeInteger:value forKey:@"kValue"];
複製程式碼
- 歸檔結束
[archiver finishEncoding];
複製程式碼
- 將資料寫入檔案中,這一步才是真正的對資料進行了持久化。
[data writeToFile:multiHome atomically:YES];
複製程式碼
反歸檔
- 從檔案中讀取NSData資料(也就是歸檔後的資料)
NSMutableData *datR = [[NSMutableData alloc]initWithContentsOfFile:
[self GetThefilePath:@"multi.archiver"]];
複製程式碼
- 建立反歸檔工具
NSKeyedUnarchiver *unchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:datR];
複製程式碼
- 進行反歸檔 注意:什麼型別的物件就要用什麼型別的方法來反歸檔,也需要用相同型別的物件來接收
CGPoint point = [unchiver decodeCGPointForKey:@"kPoint"];
NSString *info = [unchiver decodeObjectForKey:@"kInfo"];
NSInteger value = [unchiver decodeIntegerForKey:@"kValue"];
複製程式碼
- 反歸檔結束
[unchiver finishDecoding];
複製程式碼
對自定義的類進行歸檔與反歸檔
歸檔
- 準備資料
NSString *name = @"小紅";
NSInteger age = 22;
NSString *address = @"西安";
UIImage *photo = [UIImage imageNamed:@"5.png"];
Archiver *archiver = [[Archiver alloc]init];
archiver.name = name;
archiver.age = age;
archiver.address = address;
archiver.photo = photo;
複製程式碼
- 準備一個NSMutableData,用於儲存歸檔後的物件
NSMutableData *data = [[NSMutableData alloc]init];
複製程式碼
- 建立歸檔工具
NSKeyedArchiver *archive = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
複製程式碼
- 進行歸檔 歸檔的時候,是根據鍵-值對應的關係將物件轉換為NSData型別的資料。
[archive encodeObject:archiver forKey:@"arc"];
複製程式碼
- 歸檔結束
[archive finishEncoding];
複製程式碼
- 將資料寫入檔案中,這一步才是真正的對資料進行了持久化。
[data writeToFile:[self GetThefilePath:@"archiver.archiver"] atomically:YES];
複製程式碼
反歸檔
- 從檔案中讀取NSData資料(也就是歸檔後的資料)
NSMutableData *data = [[NSMutableData alloc]initWithContentsOfFile:
[self GetThefilePath:@"archiver.archiver"]];
複製程式碼
- 建立反歸檔工具
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
複製程式碼
- 進行反歸檔 注意:什麼型別的物件就要用什麼型別的方法來反歸檔,也需要用相同型別的物件來接收
Archiver *arch = [unarchiver decodeObjectForKey:@"arc"];
複製程式碼
- 反歸檔結束
[unarchiver finishDecoding];
複製程式碼