0%

Objective-C 归档

归档即把变量或对象存储到硬盘文件里,需要的时候再读取,也可以通过归档实现对象的深复制。 main.m:

#import 
#import "ClassA.h"

int main (int argc, const char * argv[])
{
    
    @autoreleasepool {
        //如果对象是NSString NSDictionary NSArray NSData NSNumber,可以使用writeToFile:atomically方法将其写入文件
        //atomically参数为是否先写入缓存
        NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:@"aaa",@"a",@"bbb",@"b",@"ccc",@"c", nil];
        if([dic writeToFile:@"/Users/fhp/Desktop/5.xml" atomically:YES]==NO)
        {
            NSLog(@"写入文件失败");
        }
        //从文件中读回,用这个方法可以也实现深复制
        NSDictionary *dic2=[NSDictionary dictionaryWithContentsOfFile:@"/Users/fhp/Desktop/5.xml"];
        for(NSString *key in dic2)
            NSLog(@"key=%@  object=%@",key,[dic2 valueForKey:key]);
        
        
        //NSKeyedArchiver可以将各种类的对象存储到文件,包括自定义的类,但生成的文件不再是明文的xml文件
        [NSKeyedArchiver archiveRootObject:dic toFile:@"/Users/fhp/Desktop/6"];
        NSDictionary *dic3=[NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/fhp/Desktop/6"];
        for(NSString *key in dic3)
            NSLog(@"key=%@  object=%@",key,[dic3 valueForKey:key]);
        //如果对象是自定义的类,需要该类遵循协议,实现encodeWithCoder和initWithCoder方法
        ClassA *a =[ClassA new];
        [a setNum:20];
        [a setName:@"nameaaa"];
        [NSKeyedArchiver archiveRootObject:a toFile:@"/Users/fhp/Desktop/7"];
        ClassA *b=[NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/fhp/Desktop/7"];
        NSLog(@"%@",b);
        
        
        //使用NSMutableDate将dic和a写入同一文件
        NSMutableData *dataArea=[NSMutableData data];
        NSKeyedArchiver * archiver=[[NSKeyedArchiver alloc] initForWritingWithMutableData:dataArea];
        [archiver encodeObject:dic forKey:@"NSDictionary"];
        [archiver encodeObject:a forKey:@"ClassA"];
        [archiver finishEncoding];
        if([dataArea writeToFile:@"/Users/fhp/Desktop/8" atomically:YES]==NO)
        {
            NSLog(@"写入文件失败");
        }
        //读取
        NSData *dataArea2=[NSData dataWithContentsOfFile:@"/Users/fhp/Desktop/8"];
        //读取的时候因为数据是固定的,不需要mutable
        NSKeyedUnarchiver *unarchive=[[NSKeyedUnarchiver alloc] initForReadingWithData:dataArea2];
        NSDictionary *dic4=[unarchive decodeObjectForKey:@"NSDictionary"];
        ClassA *a2=[unarchive decodeObjectForKey:@"ClassA"];
        [unarchive finishDecoding];
        for(NSString *key in dic4)
            NSLog(@"key=%@  object=%@",key,[dic4 valueForKey:key]);
        NSLog(@"%@",a2);
        //可以跳过写入读取文件那两个环节,实现深复制
        
                
    }
    return 0;
    
}

ClassA.h

//
//  ClassA.h
//  hello
//
//  Created by fhp on 12-2-13.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import 

@interface ClassA : NSObject//遵循NSCoding协议
{
    int num;
    NSString * name;
}
-(id)copyWithZone:(NSZone *)zone;
@property (atomic) int num;
@property (copy,atomic) NSString * name;
-(void) encodeWithCoder:(NSCoder *)aCoder;
-(id)initWithCoder:(NSCoder *)aDecoder;
//NSCoding协议必须实现encodeWithCoder和initWithCoder方法
@end

ClassA.m

#import "ClassA.h"

@implementation ClassA
@synthesize num,name;
-(NSString *)description
{
    NSString * s1=[NSString stringWithFormat:@"%d   %@",num,name];
    return s1;
}
-(id)copyWithZone:(NSZone *)zone
{
    ClassA * a=[[ClassA allocWithZone:zone] init];
    [a setNum:num];
    [a setName:name];
    return a;
}
-(void)encodeWithCoder:(NSCoder *)aCoder
{
    //归档时调用此方法
    [aCoder encodeInt:num forKey:@"ClassNum"];
    [aCoder encodeObject:name forKey:@"ClassName"];
    
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
    //解码时调用此方法还原
    num=[aDecoder decodeIntForKey:@"ClassNum"];
    name=[aDecoder decodeObjectForKey:@"ClassName"];
    return self;
}

@end