iOS 複雜物件的歸檔與反歸檔

joker_king發表於2018-12-20

歸檔與反歸檔

  • 複雜物件就是在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];
複製程式碼

相關文章