代码改变世界

iOS归档解档

2016-01-18 22:56  000aaa  阅读(402)  评论(0编辑  收藏  举报

使用NSKeyedArichiver进行归档、NSKeyedUnarchiver进行接档,这种方式会在写入、读出数据之前对数据进行序列化、反序列化操作。

 

1.对单个字符串归档

  //获取根目录
    NSString *homeDictionary = NSHomeDirectory();
    //添加储存的文件名
    NSString *homePath  = [homeDictionary stringByAppendingPathComponent:@"myText.txt"];
    
    //归档一个字符串---返回是否成功的标志
    BOOL flag = [NSKeyedArchiver archiveRootObject:@"归档字符串内容..." toFile:homePath];
    if (flag)
    {
        NSLog(@"归档成功!!!");
        //将字符串从归档内容中解档出来
       NSString *str = [NSKeyedUnarchiver unarchiveObjectWithFile:homePath];
        NSLog(@"%@",str);
    }else
    {
        NSLog(@"归档失败!!!");
    }

/*对当个的数组或者字典归档的时候  他们内部包含的对象必须都实现了NSCoding协议才能归档成功*/

 

 

2.对多种不同类型的数据同时归档

//一个CGPoint点、字符串、整数(当然很多类型都可以的,例如UIImage、float等等)
    //准备数据
    CGPoint point = CGPointMake(1.0, 2.0);
    NSString *string = @"坐标原点";
    NSInteger number = 10;
    NSString *multiHomePath = [NSHomeDirectory() stringByAppendingPathComponent:@"yyehdh.archiver"];
    NSMutableData *data = [[NSMutableData alloc]init];
    NSKeyedArchiver *archvier = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
    //对多个对象进行归档
    [archvier encodeCGPoint:point forKey:@"kPoint"];
    [archvier encodeObject:string forKey:@"kInfo"];
    [archvier encodeInteger:number forKey:@"kValue"];
    //调用归档结束关闭函数
    [archvier finishEncoding];
    //将数据归档--返回归档成功与否的标志
    BOOL flag = [data writeToFile:multiHomePath atomically:YES];
    if (flag)
    {
        NSLog(@"数据归档成功!!!!");
        //从刚才归档的文件将将数据读取出来
        NSMutableData *dataR = [[NSMutableData alloc]initWithContentsOfFile:multiHomePath];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:dataR];
        //对数据进行解档 得到相应的数据类型的数据(和归档的时候相同的数据类型)
        CGPoint pointR = [unarchiver decodeCGPointForKey:@"kPoint"];
        NSString *infoR = [unarchiver decodeObjectForKey:@"kInfo"];
        NSInteger valueR = [unarchiver decodeIntegerForKey:@"kValue"];
        //调用解档结束关闭函数
        [unarchiver finishDecoding];
        NSLog(@"%f,%f,%@,%ld",pointR.x,pointR.y,infoR,(long)valueR);
    }else
    {
        NSLog(@"归档失败!!!!");
    }

3.自定义对象归档

操作步骤

 

归档:

 

1.使用NSData实例作为归档的存储数据

 

2.添加归档的内容---使用键值对

 

3.完成归档

 

解归档:

 

1.从磁盘读取文件,生成NSData实例

 

2.根据NSData实例和初始化解归档实例

 

3.解归档,根据key访问value

 

//
//  A.h
//  归档解档
//
//  Created by admin on 16/1/18.
//  Copyright © 2016年 123. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface A : NSObject<NSCoding>
-(instancetype)initWithName:(NSString *)name icon:(UIImage *)anImage age:(NSInteger)age;
@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)NSInteger age;
@property(nonatomic,copy)UIImage *icon;

@end
//
//  A.m
//  归档解档
//
//  Created by admin on 16/1/18.
//  Copyright © 2016年 123. All rights reserved.
//

#import "A.h"

#define kNameKey @"NameKey"
#define kAgeKey @"AgeKey"
#define KIconKey @"IconKey"

@implementation A
-(instancetype)initWithName:(NSString *)name icon:(UIImage *)anImage age:(NSInteger)age;
{
    if (self = [super init])
    {
        self.name = name;
        self.age = age;
        self.icon = anImage;
    }
    return self;
}
/*
 【注】:要将一个自定义的类进行归档,那么类里面的每个属性都必须是可以被归档的,如果是不能归档的类型,我们可以把他转化为NSValue进行归档,然后在读出来的时候在转化为相应的类。
 */
#pragma mark -  通过一个给定的archiver把消息接收者进行编码
-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:kNameKey];
    [aCoder encodeInteger:_age forKey:kAgeKey];
    [aCoder encodeObject:_icon forKey:KIconKey];
}
#pragma mark -  从一个给定unarchiver的数据中返回一个初始化对象。
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init])
    {
        _name = [aDecoder decodeObjectForKey:kNameKey];
        _age = [aDecoder decodeIntegerForKey:kAgeKey];
        _icon = [aDecoder decodeObjectForKey:KIconKey];
    }
    return self;
}
#pragma mark - 返回消息接收者的一个复制的新实例。
- (id)copyWithZone:(NSZone *)zone
{
    A *copy = [[[self class] allocWithZone:zone] init];
    copy.name = [self.name copyWithZone:zone];
    copy.age = self.age;
    copy.icon = self.icon ;
    return copy;
}
@end
NSString *multiHomePath = [NSHomeDirectory() stringByAppendingPathComponent:@"ggdh.archiver"];
    A *aPerson = [[A alloc]initWithName:@"zhangsan" icon:[UIImage imageNamed:@"oicon"] age:88];
    NSLog(@"%@",[UIImage imageNamed:@"oicon"]);
    //归档
    NSMutableData *data = [[NSMutableData alloc] init];
     NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    //A类的  encodeWithCoder 将会被调用
    [archiver encodeObject:aPerson forKey:@"ObjArchiverKey"];
    [archiver finishEncoding];
    //写入文件
    BOOL flag = [data writeToFile:multiHomePath atomically:YES];
    if (flag)
    {
        NSLog(@"自定义对象归档成功!!!");
        NSData *data = [[NSMutableData alloc] initWithContentsOfFile:multiHomePath];
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        
        //获得类--解档自定义的对象
        A *readPerson = [unarchiver decodeObjectForKey:@"ObjArchiverKey"];// initWithCoder方法被调用
        [unarchiver finishDecoding];
        NSLog(@"name:%@ ~~ age:%ld ~~ icon: %@",readPerson.name,readPerson.age,readPerson.icon);
    }
    else
    {
        NSLog(@"自定义对象归档失败!!!");
    }