iOS資料持久化儲存之歸檔NSKeyedArchiver,iosnskeyedarchiver

來源:互聯網
上載者:User

iOS資料持久化儲存之歸檔NSKeyedArchiver,iosnskeyedarchiver

歸檔是一種很常用的檔案儲存方法,幾乎任何類型的對象都能夠被歸檔儲存(實際上是一種檔案儲存的形式),收集了網上的一些資料並結合自己的一些經驗,總結如下。

一、使用archiveRootObject進行簡單的歸檔

 

使用NSKeyedArichiver進行歸檔、NSKeyedUnarchiver進行接檔,這種方式會在寫入、讀出資料之前對資料進行序列化、還原序列化操作。

歸檔:

    //1.擷取檔案路徑  

  NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];   

  //2、添加儲存的檔案名稱

  NSString *path  = [docPath stringByAppendingPathComponent:@"data.archiver"];    

  //3、將一個對象儲存到檔案中

  BOOL flag = [NSKeyedArchiver archiveRootObject:@”歸檔” toFile:path];    

這種方式可以對字串、數字等進行歸檔,當然也可以對NSArray與NSDictionary進行歸檔。傳回值Flag標誌著是否歸檔成功,YES為成功,NO為失敗。

接檔:

  

  //1.擷取檔案路徑

  NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

  NSString *path=[docPath stringByAppendingPathComponent:@"person.yangyang"]; NSLog(@"path=%@",path);

  //2.從檔案中讀取對象

  [NSKeyedUnarchiver unarchiveObjectWithFile:path]  

 

使用NSKeyedUnarchiver進行接檔(還原序列化)。

這種歸檔的方式存在一個缺點:只能把一個對象歸檔進一個檔案中,那麼怎麼對多個對象進行歸檔呢?

 

二、對多個對象的歸檔

同樣是使用NSKeyedArchiver進行歸檔,不同的是同時歸檔多個對象,這裡我們舉例放入了一個CGPoint點、字串、整數(當然很多類型都可以的,例如UIImage、float等等),使用encodeXXX方法進行歸檔,最後通過writeToFile方法寫入檔案。

歸檔:寫入資料

  //準備資料    CGPoint point = CGPointMake(1.0, 2.0);    NSString *info = @"座標原點";    NSInteger value = 10;    NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];  NSString *multiHomePath = [docPath stringByAppendingPathComponent:@"multi.archiver"];    NSMutableData *data = [[NSMutableData alloc] init];    NSKeyedArchiver *archvier = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];    //對多個對象進行歸檔    [archvier encodeCGPoint:point forKey:@"kPoint"];    [archvier encodeObject:info forKey:@"kInfo"];    [archvier encodeInteger:value forKey:@"kValue"];    [archvier finishEncoding];    [data writeToFile:multiHomePath atomically:YES];  

 

 

接檔:從路徑中獲得資料構造NSKeyedUnarchiver執行個體,使用decodeXXXForKey方法獲得檔案中的對象。

  NSMutableData *dataR = [[NSMutableData alloc] initWithContentsOfFile:multiHomePath];    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:dateR];    CGPoint pointR = [unarchiver decodeCGPointForKey:@"kPoint"];    NSString *infoR = [unarchiver decodeObjectForKey:@"kInfo"];    NSInteger valueR = [unarchiver decodeIntegerForKey:@"kValue"];    [unarchiver finishDecoding];    NSLog(@"%f,%f,%@,%d",pointR.x,pointR.y,infoR,valueR);  

 

可以看出對多個對象進行歸檔還是挺方便的,這裡又出現一個問題,這裡的對象都是基本類型資料,那麼怎麼對自己定義類產生的執行個體對象進行歸檔呢?

  

三、對自訂對象進行歸檔

自訂對象,應用範圍很廣,因為它對應著MVC中的Model層,即實體類。在程式中,我們會在Model層定義很多的entity,例如User,Teacher。。

那麼對自訂對象的歸檔顯得重要的多,因為很多情況下我們需要在Home鍵之後儲存資料,在程式恢複時重新載入,那麼,歸檔便是一個好的選擇。

首先我們需要,自訂一個實體類。

//  YYViewController.m#import "YYViewController.h"#import "YYPerson.h"@interface YYViewController ()- (IBAction)saveBtnOnclick:(id)sender;- (IBAction)readBtnOnclick:(id)sender;@end@implementation YYViewController- (void)viewDidLoad{    [super viewDidLoad];}- (IBAction)saveBtnOnclick:(id)sender {    //1.建立對象    YYPerson *p=[[YYPerson alloc]init];    p.name=@"圓圓";    p.age=23;    p.height=1.7;        //2.擷取檔案路徑    NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];    NSString *path=[docPath stringByAppendingPathComponent:@"person.yangyang"];    NSLog(@"path=%@",path);        //3.將自訂的對象儲存到檔案中    [NSKeyedArchiver archiveRootObject:p toFile:path];    }- (IBAction)readBtnOnclick:(id)sender {    //1.擷取檔案路徑    NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];    NSString *path=[docPath stringByAppendingPathComponent:@"person.yangyang"];    NSLog(@"path=%@",path);        //2.從檔案中讀取對象    YYPerson *p=[NSKeyedUnarchiver unarchiveObjectWithFile:path];    NSLog(@"%@,%d,%.1f",p.name,p.age,p.height);}@end

 

 

//  YYPerson.h#import <Foundation/Foundation.h>// 如果想將一個自訂對象儲存到檔案中必須實現NSCoding協議@interface YYPerson : NSObject<NSCoding>//姓名@property(nonatomic,copy)NSString *name;//年齡@property(nonatomic,assign)int age;//身高@property(nonatomic,assign)double height;@end

 

//  YYPerson.m#import "YYPerson.h"@implementation YYPerson// 當將一個自訂對象儲存到檔案的時候就會調用該方法// 在該方法中說明如何儲存自訂對象的屬性// 也就說在該方法中說清楚儲存自訂對象的哪些屬性-(void)encodeWithCoder:(NSCoder *)aCoder{    NSLog(@"調用了encodeWithCoder:方法");    [aCoder encodeObject:self.name forKey:@"name"];    [aCoder encodeInteger:self.age forKey:@"age"];    [aCoder encodeDouble:self.height forKey:@"height"];}// 當從檔案中讀取一個對象的時候就會調用該方法// 在該方法中說明如何讀取儲存在檔案中的對象// 也就是說在該方法中說清楚怎麼讀取檔案中的對象-(id)initWithCoder:(NSCoder *)aDecoder{    NSLog(@"調用了initWithCoder:方法");    //注意:在構造方法中需要先初始化父類的方法    if (self=[super init]) {        self.name=[aDecoder decodeObjectForKey:@"name"];        self.age=[aDecoder decodeIntegerForKey:@"age"];        self.height=[aDecoder decodeDoubleForKey:@"height"];    }    return self;}@end

 

基于歸檔建立一個用於本機資料儲存的類如下:

 

#import <Foundation/Foundation.h>@interface LocalArchiverManager : NSObject/**單例模式,擷取要求管理類 *\param        param:   無 *\returns      return:     無 */+ (LocalArchiverManager *)shareManagement;/**清除本地的序列化的檔案 *\param        param:   無 *\returns      return:     無 */- (void)clearArchiverData;/**儲存快取資料 *\param        obj:   資料來源 *\param        key:     介面的名稱 *\returns      無 */- (void)saveDataArchiver:(id)obj andAPIKey:(NSString *)key;/**回去快取資料 *\param        obj:   api的key *\returns      id:     返回的資料來源 */- (id)archiverQueryAPIKey:(NSString *)key;@end

 

LocalArchiverManager.m 檔案
#import "LocalArchiverManager.h"static LocalArchiverManager *m_localArchiverMana;#define Document [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]#define ArchiverFile    [Document stringByAppendingPathComponent:@"Archiver"]@interface LocalArchiverManager()@property(nonatomic,retain)NSFileManager *fileManager;@end@implementation LocalArchiverManager+ (LocalArchiverManager *)shareManagement{    static dispatch_once_t onceTocken;    dispatch_once(&onceTocken, ^    {        m_localArchiverMana = [[LocalArchiverManager alloc] init];    });    return m_localArchiverMana;}- (id)init{    self = [super init];    if(self)    {       self.fileManager = [NSFileManager defaultManager];    }    return self;}#pragma mark private methods- (BOOL)checkPathIsExist:(NSString *)path{    return [_fileManager fileExistsAtPath:path isDirectory:nil];}- (void)createArchiverFile{    if (![self checkPathIsExist:ArchiverFile])    {        [self addNewFolder:ArchiverFile];    }}//建立目錄,path為目錄路徑(包含目錄名)- (void)addNewFolder:(NSString *)path{    [_fileManager createDirectoryAtPath:path             withIntermediateDirectories:YES                              attributes:nil                                   error:nil];}#pragma mark -#pragma mark public methods- (void)clearArchiverData{    NSError *error;    if([m_fileManager removeItemAtPath:ArchiverFile error:&error])    {        }else{        DLOG(@"清除本地序列化的檔案失敗....:%@",error);    }}- (void)saveDataArchiver:(id)obj andAPIKey:(NSString *)key{    NSMutableData *data = [[NSMutableData alloc] init];    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];    [archiver encodeObject:obj forKey:key];    [archiver finishEncoding];    [self createArchiverFile];    key = [key stringByReplacingOccurrencesOfString:@"/" withString:@"_"];    NSString *path = [ArchiverFile stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.text",key]];      BOOL isSuc = [data writeToFile:path atomically:YES];if(!isSuc) {        DLOG(@"本地序列化失敗key....:%@",key);    }}- (id)archiverQueryAPIKey:(NSString *)key{    NSString *str = [key stringByReplacingOccurrencesOfString:@"/" withString:@"_"];    NSString *path = [ArchiverFile stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.text",str]];    NSMutableData *data = [[NSMutableData alloc] initWithContentsOfFile:path];    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];    id content = [unarchiver decodeObjectForKey:key];    [unarchiver finishDecoding];    DLOG(@"content.....:%@",content);    return content;}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.