iOS數(shù)據(jù)持久化存儲(chǔ)-NSKeyedArchiver

歸檔文件

歸檔(稱為序列化)是把對(duì)象轉(zhuǎn)為字節(jié)碼,以文件的形式存儲(chǔ)到磁盤上;程序運(yùn)行過程中或者當(dāng)再次重寫打開程序的時(shí)候,可以通過解歸檔(反序列化)還原這些對(duì)象。歸檔解歸檔用于少量數(shù)據(jù)的持久化存儲(chǔ)和讀取。

歸檔和解歸檔常用API

//NSKeyedArchiver  API
+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;

- (instancetype)initForWritingWithMutableData:(NSMutableData *)data;

- (void)finishEncoding;

- (void)encodeObject:(nullable id)objv forKey:(NSString *)key;
- (void)encodeBool:(BOOL)boolv forKey:(NSString *)key;
- (void)encodeInt:(int)intv forKey:(NSString *)key;
- (void)encodeFloat:(float)realv forKey:(NSString *)key;
- (void)encodeDouble:(double)realv forKey:(NSString *)key;
//NSKeyedUnarchiver   API
+ (nullable id)unarchiveObjectWithData:(NSData *)data;
+ (nullable id)unarchiveObjectWithFile:(NSString *)path;

- (instancetype)initForReadingWithData:(NSData *)data;

- (void)finishDecoding;

- (nullable id)decodeObjectForKey:(NSString *)key;
- (BOOL)decodeBoolForKey:(NSString *)key;
- (int)decodeIntForKey:(NSString *)key;
- (float)decodeFloatForKey:(NSString *)key;
- (double)decodeDoubleForKey:(NSString *)key;

歸檔的方式:

  • 針對(duì)對(duì)象進(jìn)行歸檔(NSArray,NSDictionary等)
  • 對(duì)自定義的內(nèi)容進(jìn)行歸檔
  • 對(duì)自定義的對(duì)象進(jìn)行歸檔
1、針對(duì)對(duì)象進(jìn)行歸檔
- (void)objArchiver {
    
    //歸檔(序列化)
    NSArray *archiverAry = @[
                             @{@"Eugene" : @"ZhangYanJin"},
                             @{@"Chana" : @"LiChang"}
                             ];
    NSString *filePath = [self filePathWithName:@"Object"];
    if ([NSKeyedArchiver archiveRootObject:archiverAry toFile:filePath]) {
        NSLog(@"\n\n\n歸檔成功:路徑%@",filePath);
    }
    
    //解歸檔 (反序列化)
    NSArray *unArchiverAry = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"\n解歸檔成功 %@",unArchiverAry);
    
    /**
     總結(jié):
     *優(yōu)點(diǎn):歸檔和解歸檔操作步驟簡(jiǎn)單方便
     *缺點(diǎn):一次只能歸檔一個(gè)對(duì)象,如果歸檔多個(gè)對(duì)象,需要分開麻煩,操作繁瑣費(fèi)時(shí)
     */
}
- (void)customContentArchiver {
    
    //歸檔
    //1、使用Data存放歸檔數(shù)據(jù)
    NSMutableData *archiverData = [NSMutableData data];
    
    //2、根據(jù)Data實(shí)例創(chuàng)建和初始化歸檔對(duì)象
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiverData];
    
    //3、添加歸檔內(nèi)容(設(shè)置鍵值對(duì))
    [archiver encodeObject:@"Eugene" forKey:@"name"];
    [archiver encodeObject:@"man" forKey:@"sex"];
    [archiver encodeInt:25 forKey:@"age"];
    [archiver encodeObject:@[@"OC",@"Swift",@"Html"] forKey:@"laguage"];
    [archiver encodeObject:@{@"favorite" : @"cook"} forKey:@"life"];
    [archiver encodeCGPoint:CGPointMake(1.0, 2.0) forKey:@"point"];
    
    //4、完成歸檔
    [archiver finishEncoding];
    
    //5、將歸檔的信息存儲(chǔ)到磁盤上
    NSString *filePath = [self filePathWithName:@"CustomContent"];
    if ([archiverData writeToFile:filePath atomically:YES]) {
        NSLog(@"\n\n\n歸檔成功:路徑%@",filePath);
    }
    
    //解歸檔
    //1、從磁盤讀取文件,生成NSData實(shí)例
    NSData *unarchiverData = [NSData dataWithContentsOfFile:filePath];

    //2、根據(jù)Data實(shí)例創(chuàng)建和初始化解歸檔對(duì)象
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverData];

    //3、解歸檔,根據(jù)key值訪問
    NSString *name = [unarchiver decodeObjectForKey:@"name"];
    NSDictionary *life = [unarchiver decodeObjectForKey:@"life"];
    NSLog(@"\n解歸檔成功: %@ %@",name,life);
    
    //4、完成解歸檔
    [unarchiver finishDecoding];

    /**
     總結(jié):
     *優(yōu)點(diǎn):可以同時(shí)歸檔多個(gè)對(duì)象、以及不同類型的對(duì)象(如:Int、CGFloat、CGPoint)
     *缺點(diǎn):這里的對(duì)象都是基本類型數(shù)據(jù),如果我想對(duì)自己定義類生成的實(shí)例對(duì)象進(jìn)行歸檔,這樣做將使操作又變得繁瑣費(fèi)時(shí)了
     */
}
- (void)customObjectArchiver {
    
    //序列化和反序列化遵循NSCoding協(xié)議的自定義類
    
    //歸檔
    Person *person = [[Person alloc] init];
    person.name = @"Eugene";
    person.sex = @"man";
    person.age = 25;
    person.height = 175;
    
    NSString *filePath = [self filePathWithName:@"CustomObject"];

    if ([NSKeyedArchiver archiveRootObject:person toFile:filePath]) {
        NSLog(@"\n\n\n歸檔成功:路徑%@",filePath);
    }
    
    //解歸檔
    Person *unArchiverObj = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"\n解歸檔成功: %@ %@",unArchiverObj,unArchiverObj.name);
    
}
- (NSString *)filePathWithName:(NSString *)name {

    name = [[NSString alloc] initWithFormat:@"%@.archiver",name];
    
    //歸檔后的文件是加密的,所以歸檔文件的擴(kuò)展名可以隨意取,我這里后綴用archiver
    return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:name];
}

注意:

  • 1、默認(rèn)情況下,只能對(duì)NSDate, NSNumber, NSString, NSArray, or NSDictionary來進(jìn)行歸檔。
  • 2、若對(duì)自定義的對(duì)象進(jìn)行歸檔,需要實(shí)現(xiàn)NSCoding協(xié)議,并實(shí)現(xiàn)NSCoding方法。
  • NSCoding協(xié)議的方法:
  • - (void)encodeWithCoder:(NSCoder *)aCoder;
  • - (instancetype)initWithCoder:(NSCoder *)aDecoder;
  • 3、如果用了繼承,則子類一定要重寫NSCoding協(xié)議的兩個(gè)方法。

附:歸檔Demo

寫在最后

推薦:
一個(gè)簡(jiǎn)單、線程安全的基于 key-value 的緩存框架EGOCache

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1、 沙盒概念基本介紹 iOS 應(yīng)用程序只能在該 app 的文件系統(tǒng)中讀取。這個(gè)默認(rèn)的 app 文件系統(tǒng)就是我們說...
    Laughingg閱讀 2,762評(píng)論 2 10
  • 在程序開發(fā)中,數(shù)據(jù)層永遠(yuǎn)是程序的核心結(jié)構(gòu)之一。我們將現(xiàn)實(shí)事物進(jìn)行抽象,使之變成一個(gè)個(gè)數(shù)據(jù)。對(duì)這些數(shù)據(jù)的加工處理是代...
    帥不過oneS閱讀 624評(píng)論 0 1
  • 數(shù)據(jù)持久化的相關(guān)知識(shí) 四種將數(shù)據(jù)持久化存儲(chǔ)到iOS文件系統(tǒng)的機(jī)制: plist 對(duì)象歸檔 iOS的嵌入式關(guān)系數(shù)據(jù)庫(kù)...
    melouverrr閱讀 644評(píng)論 0 0
  • 一、數(shù)據(jù)持久化概述 數(shù)據(jù)持久化就是數(shù)據(jù)的永久存儲(chǔ)。其本質(zhì)是將數(shù)據(jù)保存為文件,存到程序的沙盒中。 1、數(shù)據(jù)持久化的方...
    lilinjianshu閱讀 510評(píng)論 0 1
  • 在程序開發(fā)中,數(shù)據(jù)層永遠(yuǎn)是程序的核心結(jié)構(gòu)之一。我們將現(xiàn)實(shí)事物進(jìn)行抽象,使之變成一個(gè)個(gè)數(shù)據(jù)。對(duì)這些數(shù)據(jù)的加工處理是代...
    sindri的小巢閱讀 16,845評(píng)論 13 85