iOS數(shù)據(jù)持久化——?dú)w檔NSKeyedArchiver(NSCoding)

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

歸檔在iOS中是另一種形式的序列化,只要遵循了 NSCoding 協(xié)議的對(duì)象都可以通過(guò)它實(shí)現(xiàn)序列化。由于絕大多數(shù)支持存儲(chǔ)數(shù)據(jù)的類都遵循了 NSCoding 協(xié)議,因此,對(duì)于大多數(shù)類來(lái)說(shuō),歸檔相對(duì)而言還是比較容易實(shí)現(xiàn)的。

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

1、遵循NSCoding協(xié)議

NSCoding 協(xié)議聲明了兩個(gè)方法,這兩個(gè)方法都是必須實(shí)現(xiàn)的:

  • encodeWithCoder:用來(lái)說(shuō)明如何將對(duì)象編碼到歸檔中。
    每次歸檔對(duì)象時(shí),都會(huì)調(diào)用這個(gè)方法。一般在這個(gè)方法里面指定如何歸檔對(duì)象中的每個(gè)實(shí)例變量,可以使用 encodeObject:forKey: 方法歸檔實(shí)例變量。

  • initWithCoder:用來(lái)說(shuō)明如何進(jìn)行解檔來(lái)獲取一個(gè)新對(duì)象。
    每次從文件中恢復(fù)(解碼)對(duì)象時(shí),都會(huì)調(diào)用這個(gè)方法。一般在這個(gè)方法里面指定如何解碼文件中的數(shù)據(jù)為對(duì)象的實(shí)例變量,可以使用 decodeObject:forKey 方法解碼實(shí)例變量。

// 1.遵循NSCoding協(xié)議 
@interface Person : NSObject <NSCoding> 
// 2.設(shè)置屬性
@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歸檔

調(diào)用 NSKeyedArchiverarchiveRootObject:toFile: 方法把對(duì)象歸檔。

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解檔

調(diào)用 NSKeyedUnarchiverunarchiveObjectWithFile: 方法從文件中解檔對(duì)象。

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];
}
  • 必須遵循并實(shí)現(xiàn) NSCoding 協(xié)議
  • 保存文件的擴(kuò)展名可以任意指定
  • 繼承時(shí)必須先調(diào)用父類的歸檔解檔方法,這里因?yàn)楦割愂?NSObject,就不用了。如果父類也遵守了 NSCoding 協(xié)議,請(qǐng)注意:
    • 應(yīng)該在encodeWithCoder:方法中加上一句 [super encodeWithCode:encode] ,確保繼承的實(shí)例變量也能被編碼,即也能被歸檔。
    • 應(yīng)該在initWithCoder:方法中加上一句 self = [super initWithCoder:decoder],確保繼承的實(shí)例變量也能被解碼,即也能被恢復(fù)。

通過(guò)文件讀寫(xiě)(plist)保存的數(shù)據(jù)是直接顯示出來(lái)的,不安全。而通過(guò) NSKeydeArchiver 歸檔方法保存的數(shù)據(jù)在文件中打開(kāi)是編碼,更安全。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容