iOS歸檔和解檔

關鍵詞:

  • 歸檔:數(shù)據(jù)持久化的一種方式,是將數(shù)據(jù)進行編碼序列化之后存儲的過程续滋。適用于小量數(shù)據(jù)的存儲舅锄。

  • 解檔:對歸檔的數(shù)據(jù)進行解碼,拿到當初歸檔的數(shù)據(jù)的過程则吟。

  • NSCoding:A protocol that enables an object to be encoded and decoded for archiving and distribution.
    一種能夠?qū)ο筮M行編碼和解碼槐臀,以實現(xiàn)歸檔和解檔案的協(xié)議,也就是說只有遵循了NSCoding這個協(xié)議才能實現(xiàn)數(shù)據(jù)的歸檔和解檔氓仲。
    NSCoding 是一個簡單的協(xié)議水慨,通過 -initWithCoder: 和 encodeWithCoder:方法,遵循NSCoding協(xié)議的類可以被序列化和反序列化敬扛,這樣可以將數(shù)據(jù)歸檔到磁盤上晰洒。

沙盒、Archiver 啥箭、encode谍珊、UnArchiver、decode急侥、砌滞、NSCoder炼七、NSKeyedArchiver、NSKeyedUnarchiver布持、NSKeyedArchiverDelegate豌拙、NSKeyedUnarchiverDelegate

歸檔的缺點:歸檔的形式來保存數(shù)據(jù),只能一次性歸檔保存以及一次性解壓题暖。所以只能針對小量數(shù)據(jù)按傅,而且對數(shù)據(jù)操作比較笨拙,即如果想改動數(shù)據(jù)的某一小部分胧卤,還是需要解壓整個數(shù)據(jù)或者歸檔整個數(shù)據(jù)

實現(xiàn)過程

1唯绍、歸檔和解檔一個對象

ViewController

ViewController.m

#import "ViewController.h"
#import "Person.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    Person *person = [[Person alloc]init];
    person.name = @"小明";
    person.age = 23;
    person.gender = GenderMan;
    person.isAdult = YES;
    person.labelArray = @[@"陽光",@"萌新",@"正太"];
    person.car.color = [UIColor blackColor];
    
    // 歸檔Person對象
    [NSKeyedArchiver archiveRootObject:person toFile:[Person archivePath]];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    // 解檔Person屬性,并打印
    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:[Person archivePath]];
    NSLog(@"%@",person.name);
    NSLog(@"%ld",person.age);
    NSLog(@"%ld",person.gender);
    NSLog(@"%d",person.isAdult);
    NSLog(@"%@",person.labelArray);
    NSLog(@"%@",person.car.color);
}
  • 為了方便測試枝誊,我們直接在viewDidLoad創(chuàng)建了一個person對象况芒,并給其屬性賦了值,之后將person這個對象進行了歸檔叶撒。
  • 在touch方法里面我們解檔了person對象绝骚,然后將歸檔的屬性值打印了出來。
  • 這里需要注意一下祠够,項目中根據(jù)情況压汪,有時候歸檔和解檔需要異步處理,自己添加子線程即可古瓤。

這個過程就實現(xiàn)了對一個對象的歸檔和解檔止剖,那么在Person類里面操作如下:

Person

Person.h

#import <Foundation/Foundation.h>
#import "Car.h"

typedef NS_ENUM(NSInteger,Gender){
    GenderMan=1,
    GenderWoman
};

@interface Person : NSObject<NSCoding>//歸檔解檔需要遵守NSCopying協(xié)議

@property (nonatomic, copy  ) NSString   *name;//姓名
@property (nonatomic        ) Gender     gender;//性別
@property (nonatomic        ) NSUInteger age;//年齡
@property (nonatomic        ) BOOL       isAdult;//是否成年
@property (nonatomic, strong) NSArray    *labelArray;//性格標簽數(shù)組

@property (nonatomic, strong) Car        *car;

// 歸檔地址
+ (NSString *)archivePath;

@end

Person.m

#import "Person.h"

@implementation Person

- (void)encodeWithCoder:(NSCoder *)aCoder {
    // 歸檔
    // 這里的Key為了方便和減少錯誤,最好就用屬性作為Key
    // 不同類型的屬性有不同的歸檔和解檔方法

    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeInteger:self.gender forKey:@"gender"];
    [aCoder encodeInteger:self.age forKey:@"age"];
    [aCoder encodeBool:self.isAdult forKey:@"isAdult"];
    [aCoder encodeObject:self.labelArray forKey:@"labelArray"];
    // 這里注意一下落君,歸檔一個對象的時候穿香,這個對象也需要實現(xiàn)NSCoding協(xié)議和相應的方法,不然的話直接閃退绎速,閃退日志如下:
    // -[Car encodeWithCoder:]: unrecognized selector sent to instance
    [aCoder encodeObject:self.car forKey:@"car"];
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        // 解檔皮获,賦值
        // 這里的Key需與歸檔時的Key一致
        
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.gender = [aDecoder decodeIntegerForKey:@"gender"];
        self.age = [aDecoder decodeIntegerForKey:@"age"];
        self.isAdult = [aDecoder decodeBoolForKey:@"isAdult"];
        self.labelArray = [aDecoder decodeObjectForKey:@"labelArray"];
        self.car = [aDecoder decodeObjectForKey:@"car"];
    }
    return self;
}

// 歸檔地址
+ (NSString *)archivePath {
    NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
    return [path stringByAppendingString:@"PersonCache"];
}

//通過get方法創(chuàng)建car對象,外部不再需要每次創(chuàng)建朝氓,直接使用點語法給car的屬性賦值即可魔市。
- (Car *)car {
    if (!_car) {
        _car = [[Car alloc]init];
    }
    return _car;
}
@end
  • 這里的Person和Car是我們創(chuàng)建的兩個類,算是兩個Model赵哲。
  • Person中有一些屬性待德,特別的它有一個屬性car。
  • 歸檔需要 有一個歸檔的地址枫夺,我們直接用類方法返回一個歸檔路徑将宪。

Car

Car.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Car : NSObject<NSCoding>//Car也需要遵循NSCoding協(xié)議

@property (nonatomic, strong) UIColor *color;//汽車顏色

@end

Car.m

#import "Car.h"

@implementation Car

- (void)encodeWithCoder:(NSCoder *)aCoder {
    
    [aCoder encodeObject:self.color forKey:@"color"];
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super init]) {
        
        self.color = [aDecoder decodeObjectForKey:@"color"];
    }
    return self;
}
@end
  • Car有一個屬性color,要想歸檔Person對象的car屬性,則需要Car也遵循NSCoding協(xié)議较坛,而且也需要實現(xiàn)自己的歸檔和解檔方法印蔗。

到這里歸檔和解檔一個對象的操作就完成了

小結(jié)

總結(jié)一下歸檔一個對象需要以下幾個步驟:
1、遵循NSCoding協(xié)議<NSCoding>
2丑勤、實現(xiàn)歸檔和解檔的方法

  • (void)encodeWithCoder:(NSCoder *)aCoder
  • (nullable instancetype)initWithCoder:(NSCoder *)aDecoder

3华嘹、歸檔或者解檔

// 歸檔Person
[NSKeyedArchiver archiveRootObject:person toFile:[Person archivePath]];
// 解檔Person
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:[Person archivePath]];

2、歸檔一個數(shù)組法竞、字典等

與歸檔一個對象一樣的原理耙厚,這里講歸檔數(shù)組的地址寫了一個宏。

//數(shù)組歸檔地址
#define kChachArrayPath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingString:@"MyArray"]
// 歸檔數(shù)組
NSArray *array = @[@"陽光",@"萌新",@"正太"];
[NSKeyedArchiver archiveRootObject:array toFile:kChachArrayPath];
// 解檔數(shù)組
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:kChachArrayPath];
NSLog(@"%@",array[0]);

這種只歸檔了一個數(shù)組的方式如果在項目中使用岔霸,建議不要這樣用薛躬,因為不方便管理。推薦使用NSUserDefaults呆细。根據(jù)具體的項目情況選擇最合適的型宝。

demo

https://github.com/Mexiang/Archive

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市絮爷,隨后出現(xiàn)的幾起案子趴酣,更是在濱河造成了極大的恐慌,老刑警劉巖略水,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件价卤,死亡現(xiàn)場離奇詭異,居然都是意外死亡渊涝,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門床嫌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跨释,“玉大人,你說我怎么就攤上這事厌处”钐福” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵阔涉,是天一觀的道長缆娃。 經(jīng)常有香客問我,道長瑰排,這世上最難降的妖魔是什么贯要? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮椭住,結(jié)果婚禮上崇渗,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好宅广,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布葫掉。 她就那樣靜靜地躺著,像睡著了一般跟狱。 火紅的嫁衣襯著肌膚如雪俭厚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天驶臊,我揣著相機與錄音挪挤,去河邊找鬼。 笑死资铡,一個胖子當著我的面吹牛电禀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笤休,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尖飞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了店雅?” 一聲冷哼從身側(cè)響起政基,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闹啦,沒想到半個月后沮明,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡窍奋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年荐健,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琳袄。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡江场,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窖逗,到底是詐尸還是另有隱情址否,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布碎紊,位于F島的核電站佑附,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仗考。R本人自食惡果不足惜音同,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痴鳄。 院中可真熱鬧瘟斜,春花似錦缸夹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霎终。三九已至汁汗,卻和暖如春哺眯,著一層夾襖步出監(jiān)牢的瞬間惭等,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工祈坠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留纷跛,地道東北人扫夜。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓谱邪,卻偏偏與公主長得像炮捧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惦银,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

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