iOS數據持久化——歸檔NSKeyedArchiver(NSCoding)

前面兩種方式(plist文件讀寫NSUserDefaults偏好設置)只能保存 plist 支持的基本數據類型,那么要保存自定義的類對象,蘋果提供了NSKeydeArchiver歸檔。

歸檔在iOS中是另一種形式的序列化,只要遵循了 NSCoding 協議的對象都可以通過它實現序列化。由于絕大多數支持存儲數據的類都遵循了 NSCoding 協議,因此,對于大多數類來說,歸檔相對而言還是比較容易實現的。

如果對象是 NSString、NSDictionary、NSArray、NSData、NSNumber 等類型,可以直接用 NSKeyedArchiver 歸檔和 NSKeyedUnarchiver 解檔。

1、遵循NSCoding協議

NSCoding 協議聲明了兩個方法,這兩個方法都是必須實現的:

  • encodeWithCoder:用來說明如何將對象編碼到歸檔中。
    每次歸檔對象時,都會調用這個方法。一般在這個方法里面指定如何歸檔對象中的每個實例變量,可以使用 encodeObject:forKey: 方法歸檔實例變量。

  • initWithCoder:用來說明如何進行解檔來獲取一個新對象。
    每次從文件中恢復(解碼)對象時,都會調用這個方法。一般在這個方法里面指定如何解碼文件中的數據為對象的實例變量,可以使用 decodeObject:forKey 方法解碼實例變量。

// 1.遵循NSCoding協議 
@interface Person : NSObject <NSCoding> 
// 2.設置屬性
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) NSInteger age;
@end

@implementation Person 
// 解檔
- (id)initWithCoder:(NSCoder *)aDecoder {
      if (self = [super init]) {
          self.name = [aDecoder decodeObjectForKey:@"name"];
          self.age = [aDecoder decodeIntegerForKey:@"age"];
      }
      return self;
}
// 歸檔
- (void)encodeWithCoder:(NSCoder *)aCoder {
      [aCoder encodeObject:self.name forKey:@"name"];
      [aCoder encodeInteger:self.age forKey:@"age"];
}
@end
2、NSKeyedArchiver歸檔

調用 NSKeyedArchiverarchiveRootObject:toFile: 方法把對象歸檔。

NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).lastObject; 
NSString *file = [path stringByAppendingPathComponent:@"person.data"];
Person *person = [[Person alloc] init];
person.name = @"Jay";
person.age = 18;
[NSKeyedArchiver archiveRootObject:person toFile:file];
3、NSKeyedUnarchiver解檔

調用 NSKeyedUnarchiverunarchiveObjectWithFile: 方法從文件中解檔對象。

NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).lastObject; 
NSString *file = [path stringByAppendingPathComponent:@"person.data"];
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
if (person) {
    self.nameLable.text = person.name;
    self.ageLable.text = [NSString stringWithFormat:@"%ld", person.age];
}
  • 必須遵循并實現 NSCoding 協議
  • 保存文件的擴展名可以任意指定
  • 繼承時必須先調用父類的歸檔解檔方法,這里因為父類是 NSObject,就不用了。如果父類也遵守了 NSCoding 協議,請注意:
    • 應該在encodeWithCoder:方法中加上一句 [super encodeWithCode:encode] ,確保繼承的實例變量也能被編碼,即也能被歸檔。
    • 應該在initWithCoder:方法中加上一句 self = [super initWithCoder:decoder],確保繼承的實例變量也能被解碼,即也能被恢復。

通過文件讀寫(plist)保存的數據是直接顯示出來的,不安全。而通過 NSKeydeArchiver 歸檔方法保存的數據在文件中打開是編碼,更安全。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容