iOS開發(fā)基礎-數(shù)據(jù)存儲方式(歸檔)

** 前言:**
歸檔是iOS開發(fā)中數(shù)據(jù)存儲常用的技巧,歸檔可以直接將對象儲存成文件,把文件讀取成對象。相對于plist或者userdefault形式,歸檔可以存儲的數(shù)據(jù)類型更加多樣,并且可以存取自定義對象。對象歸檔的文件是保密的,在磁盤上無法查看文件中的內(nèi)容,更加安全。

一、系統(tǒng)對象的歸檔

兩個核心方法
\+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
\+ (nullable id)unarchiveObjectWithFile:(NSString *)path;

使用NSKeyedArichiver進行歸檔、NSKeyedUnarchiver進行接檔,這種方式會在寫入、讀出數(shù)據(jù)之前對數(shù)據(jù)進行序列化、反序列化操作。

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:
                     @"xiaoming", @"name",
                     @15, @"age",
                     @"1234567", @"studentid",
                     @"boy", @"sex",nil];
NSArray *array = @[@"數(shù)據(jù)1",@"數(shù)據(jù)2",@"數(shù)據(jù)3",@"數(shù)據(jù)4"];

NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];

NSString *path1 =[docPath stringByAppendingPathComponent:@"person.archiver"];//后綴名可以隨意命名
NSString *path2 =[docPath stringByAppendingPathComponent:@"data.archiver"];

BOOL flag1 = [NSKeyedArchiver archiveRootObject:array toFile:path1];
BOOL flag2 = [NSKeyedArchiver archiveRootObject:dic toFile:path2];

這種方式可以對基本數(shù)據(jù)類型進行歸檔,比如字符串,NSNumber,當然常用的是對NSArray與NSDictionary進行歸檔。返回值Flag標志著是否歸檔成功,YES為成功,NO為失敗。

解檔:

NSDictionary *dic = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];

二、對多種類型數(shù)據(jù)進行歸檔

同樣是使用NSKeyedArchiver進行歸檔,不同的是同時歸檔多個數(shù)據(jù),這里我們舉例放入了一個CGPoint點、字符串、整數(shù)(當然很多類型都可以的,例如UIImage、float等等),使用encodeXXX方法進行歸檔,最后通過writeToFile方法寫入文件。
歸檔:寫入數(shù)據(jù)

// NSKeyedArchiver 可以對多種類型數(shù)據(jù)進行歸檔
CGPoint point = CGPointMake(10, 20);
NSString *name = @"xiaoMing";
NSInteger age = 10;

NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [docPath stringByAppendingPathComponent:@"multiData.arch"];

NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archvier = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

// 對多種類型數(shù)據(jù)歸檔
[archvier encodeCGPoint:point forKey:@"point"];
[archvier encodeObject:name forKey:@"name"];
[archvier encodeInteger:age forKey:@"age"];
[archvier finishEncoding];
[data writeToFile:path atomically:YES];

解檔:從路徑中獲得數(shù)據(jù)構造NSKeyedUnarchiver實例,使用decodeXXXForKey方法獲得文件中的對象。

NSMutableData *dataR = [[NSMutableData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:dataR];
CGPoint pointR = [unarchiver decodeCGPointForKey:@"point"];
NSString *nameR = [unarchiver decodeObjectForKey:@"name"];
NSInteger ageR = [unarchiver decodeIntegerForKey:@"age"];
[unarchiver finishDecoding];
NSLog(@"%f,%f,%@,%d",pointR.x,pointR.y,nameR,ageR);

三、對自定義對象進行歸檔

除了字典和數(shù)組,開發(fā)中往往需要自定義一些對象,也就是MVC中的model層。
那么如何對自定義對象進行存取就顯得重要的多,歸檔是個不錯的好選擇。

我們有個自定義對象叫做 person。
person.h

#import <Foundation/Foundation.h>

// 歸檔自定義對象該對象必須實現(xiàn)nscoding 協(xié)議
@interface person : NSObject<NSCoding>

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSInteger age;
@property (nonatomic,assign) double height;

@end

person.m 需要重寫兩個協(xié)議方法

-(void)encodeWithCoder:(NSCoder *)aCoder方法:
-(id)initWithCoder:(NSCoder *)aDecoder方法:

#import "person.h"

@implementation person

// 當將一個自定義對象保存到文件的時候就會調(diào)用該方法
// 在該方法中說明如何存儲自定義對象的屬性
// 也就說在該方法中說清楚存儲自定義對象的哪些屬性
-(void)encodeWithCoder:(NSCoder *)aCoder
{
         NSLog(@"調(diào)用了encodeWithCoder:方法");
         [aCoder encodeObject:self.name forKey:@"name"];
         [aCoder encodeInteger:self.age forKey:@"age"];
         [aCoder encodeDouble:self.height forKey:@"height"];
}

// 當從文件中讀取一個對象的時候就會調(diào)用該方法
// 在該方法中說明如何讀取保存在文件中的對象
// 也就是說在該方法中說清楚怎么讀取文件中的對象
-(id)initWithCoder:(NSCoder *)aDecoder
{
     NSLog(@"調(diào)用了initWithCoder:方法");
     //注意:在構造方法中需要先初始化父類的方法
     if (self=[super init]) {
             self.name=[aDecoder decodeObjectForKey:@"name"];
             self.age=[aDecoder decodeIntegerForKey:@"age"];
             self.height=[aDecoder decodeDoubleForKey:@"height"];
         }
     return self;
 }

@end

對person對象進行歸檔解檔:

- (IBAction)archiveSelfObject:(id)sender {

    person *xiaoMu = [[person alloc] init];
    xiaoMu.name = @"小木";
    xiaoMu.age = 25;
    xiaoMu.height = 180;
    // 獲取文件路徑
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [docPath stringByAppendingPathComponent:@"person.arch"];
    // 保存自定義對象
    [NSKeyedArchiver archiveRootObject:xiaoMu toFile:path];
    
    // 解檔
    person *person2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSLog(@"%@,%d,%.1fcm",person2.name,person2.age,person2.height);
}

返回結(jié)果:


控制臺日志

** 相關 **
iOS 沙盒目錄結(jié)構及正確使用

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

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