美文网首页
iOS 归档NSKeyedArchiver

iOS 归档NSKeyedArchiver

作者: 请叫我魔法师 | 来源:发表于2017-10-25 11:51 被阅读0次

    一、归档NSKeyedArchiver和解归档NSKeyedUnarchiver

    1.首先确定存储路径。

    NSHomeDirectory和NSSearchPathForDirectoriesInDomains的区别

    1.NSHomeDirectory
    NSString *path1 = NSHomeDirectory();
    NSLog(@"path1:%@", path1);
    //path1:/Users/yuanjun/Library/Application Support/iPhone Simulator/4.2/Applications/172DB70A-145B-4575-A31E-D501AC6EA830
    
    2.NSSearchPathForDirectoriesInDomains
    NSString *path2 = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSLog(@"path2:%@", path2);
    //path2:/Users/yuanjun/Library/Application Support/iPhone Simulator/4.2/Applications/172DB70A-145B-4575-A31E-D501AC6EA830/Library/Caches
    
    NSString *docPath =  [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSLog(@"path3:%@", path3);
    //path3:/Users/yuanjun/Library/Application Support/iPhone Simulator/4.2/Applications/172DB70A-145B-4575-A31E-D501AC6EA830/Documents
    

    2.需要归档的对象
    h文件,最后归档协议NSCoding

    #import <Foundation/Foundation.h>
    
    @interface Dog : NSObject <NSCoding>
    
    @property (nonatomic, copy) NSString *dogName;
    @property (nonatomic, assign) NSInteger dogAge;
    
    @end
    

    m文件,实现归档和反归档协议方法

    //归档
    //对dog对象进行归档时,此方法执行
    //对dog中想要进行归档的所有属性,进行序列化操作
    - (void)encodeWithCoder:(NSCoder *)aCoder {
        
        [aCoder encodeObject:self.dogName forKey:@"dogName"]; //归档普通对象
        [aCoder encodeInteger:self.dogAge forKey:@"dogAge"]; //归档数字
    }
    
    //反归档
    //对dog对象进行反归档时,该方法执行
    //创建一个新的dog对象,所有属性都是通过反序列化得到
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        
        if (self = [super init]) {
            
            self.dogName = [aDecoder decodeObjectForKey:@"dogName"];
            self.dogAge = [aDecoder decodeIntegerForKey:@"dogAge"];
        }
        return self;
    }
    

    控制器中操作,存储数据和取出数据

        Dog *heiZi = [[Dog alloc] init];
        heiZi.dogName = @"黑子";
        heiZi.dogAge = 5;
        
    //    确定存储路径
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        path = [path stringByAppendingString:@"dogInfo"];
    
    //    初始化数据对象
        NSMutableData *dogData = [[NSMutableData alloc] init];
        
    //    初始化归档对象
        NSKeyedArchiver *archive = [[NSKeyedArchiver alloc] initForWritingWithMutableData:dogData];
        
    //    开始归档
        [archive encodeObject:heiZi forKey:@"heiZi"];
        [archive finishEncoding];
        
    //    判断是否成功
        BOOL finish = [dogData writeToFile:path atomically:YES];
        if (finish) {
            NSLog(@"666_SunDePrint_999:%@", @"归档成功");
        }else{
            NSLog(@"666_SunDePrint_999:%@", @"归档失败");
        }
        
    //也可以用直接类方法根据路径直接归档
    //[NSKeyedArchiver archiveRootObject:heiZi toFile:path];
        
    //    通过路径取出存储数据
        NSData *data = [NSData dataWithContentsOfFile:path];
        //    反归档
        NSKeyedUnarchiver *unArchive = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
        Dog *newDog =  [unArchive decodeObjectForKey:@"heiZi"];
        
    //可以直接用类方法,根据路径直接解归档
    //    Dog *newDog = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
        NSLog(@"666_SunDePrint_999:%@--%ld", newDog.dogName, newDog.dogAge);
    

    结果:


    归档结果.png

    二、利用runtime归档 (结合KVC)

    利用runtime class_copyPropertyList 方法获得对象的属性列表。遍历数组,根据得到的属性名结合KVC方法进行归档和解归档。

    #import "Dog.h"
    #import <objc/runtime.h>
    
    @implementation Dog
    
    //归档
    //对dog对象进行归档时,此方法执行
    //对dog中想要进行归档的所有属性,进行序列化操作
    - (void)encodeWithCoder:(NSCoder *)aCoder {
        
        unsigned int proCount;
        objc_property_t *pros = class_copyPropertyList([self class], &proCount);
        for (int i = 0; i < proCount; i++) {
            
            objc_property_t pro = pros[i];
            
            NSString *proName = [NSString stringWithCString:property_getName(pro) encoding:NSUTF8StringEncoding];
            NSLog(@"666_SunDePrint_999:%@", proName);
    
            [aCoder encodeObject:[self valueForKey:proName] forKey:proName];
        }
        free(pros);
    }
    
    //解归档
    //对dog对象进行解归档时,该方法执行
    //创建一个新的dog对象,所有属性都是通过反序列化得到
    - (instancetype)initWithCoder:(NSCoder *)aDecoder {
        
        if (self = [super init]) {
            
            unsigned int proCount;
            objc_property_t *pros = class_copyPropertyList([self class], &proCount);
            for (int i = 0; i < proCount; i++) {
                
                objc_property_t pro = pros[i];
                
                NSString *proName = [NSString stringWithCString:property_getName(pro) encoding:NSUTF8StringEncoding];
                [self setValue:[aDecoder decodeObjectForKey:proName] forKey:proName];
            }
            free(pros);
        }
    
        return self;
    }
    @end
    

    相关文章

      网友评论

          本文标题:iOS 归档NSKeyedArchiver

          本文链接:https://www.haomeiwen.com/subject/nicqpxtx.html