iOS开发之归档

归档是一种对象都可以实现的更加常规的序列化方式。适用对模型对象进行归档的技术可以轻松将复杂对象写入文件和从文件中进行读取。大多数支持存储数据的Foundation和Cocos Touch类都遵循NSCoding协议(不过有些例外,例如UIIamge),因此对于大多数系统提供的类而言,归档比较轻松。如果是自定义的类,则需要自己实现NSCoding协议的编码和解码方法。下面还是用上篇文章中的例子,但是换成归档的方式进行持久化。


1、创建数据模型

创建类BIDFourLines,继承NSObject,定义有个NSArray类型的属性用来存储4个文本字段中的字符串。

#import <Foundation/Foundation.h>

@interface BIDFourLines : NSObject<NSCoding,NSCopying>

@property (nonatomic, copy) NSArray * lines;

@end

注意我们让它遵循了NSCoding和NSCopy协议,下面分别实现两个协议中的方法。

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super init];
    if (self) {
        self.lines = [aDecoder decodeObjectForKey:@"lines"];
    }
    return self;
}

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


这两个方法都传递了一个NSCoder类型的实例,分别用于解码和编码。
-(id)copyWithZone:(NSZone *)zone
{
    BIDFourLines * copy = [BIDFourLines allocWithZone:zone];
    NSMutableArray * array = [NSMutableArray array];
    if (copy) {
        for (id line in self.lines) {
            [array addObject:[line copy]];
        }
    }
    copy.lines = array;
    return copy;
}

对于任何数据模型,实现NSCopy协议都是非常有用的,通过它可以拷贝一个完全相同的对象。在copyWithZone方法中,我们创建了一个新的实例,并为它的属性设置相同的值。


2、实现ViewController

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (nonatomic, strong) IBOutletCollection(UITextField)NSArray * lineFields;

@end

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    

    if ([[NSFileManager defaultManager] fileExistsAtPath:[self getFilePath]]) {
        NSMutableData * data = [NSData dataWithContentsOfFile:[self getFilePath]];
        NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        NSArray * array = [unarchiver decodeObjectForKey:@"hahaha"];
        [unarchiver finishDecoding];
        for (int i = 0; i<self.lineFields.count; i++) {
            UITextField * textField = self.lineFields[i];
            textField.text = array[i];
        }
    }
    
    
    /*注册通知*/
    NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
	[center addObserver:self
               selector:@selector(applicationWillResignActive:)
                   name:UIApplicationWillResignActiveNotification
                 object:nil];
}

- (NSString *)getFilePath
{
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentDirectory = paths[0];
    NSString * dataPath = [documentDirectory stringByAppendingPathComponent:@"textFeildText.archive"];
    return dataPath;
}

- (void)applicationWillResignActive:(NSNotification *)notification
{
    NSArray * textArray = [self.lineFields valueForKey:@"text"];
    NSMutableData * data = [[NSMutableData alloc] init];
    NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:textArray forKey:@"hahaha"];
    [archiver finishEncoding];
    [data writeToFile:[self getFilePath] atomically:YES];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end


通过注册通知,每次应用程序进入后台,都会调用applicationWillResignActive方法来保存数据。首先创建一个NSMutableData实例,用于保存归档后的数据。然后创建NSKeyedArchiver实例,用于把数据归档到data中。最后将生成的data写入文件。

当前viewController展现时,首先判断指定路径下有无归档文件,如果有,从归档文件中创建data实例,并创建一个NSKeyedUnarchiver进行解码。

值得注意的时,对数组或者字典进行归档时,要确保数组或字典中的元素也同时要遵循NSCoding协议,只有这样,其中的对象才可以和数组本身一起写入到文件当中,然后从文件中读取出来重新回到数组或字典当中。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值