Runtime实例运用-归档解档

解档归档是存储方法之一,我们先来回忆一下都有哪些存储方法。

一.回忆存储方法:

  1. XML归档解档
  2. NSUserDefault
  3. NSKeyedArchiver归档解档
  4. sqlite

1.XML归档解档

1)数据类型只支持 NSString、NSDictionary、NSArayy、NSData、NSNumber(如果你想的话,可以将基本数据类型转换为NSNumber再进行归档)
2)一般保存.plist文件
3)运用:

 NSArray *array = @[@"test",@"test2"];
 NSString *path3 = [[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]stringByAppendingPathComponent:@"array.plist"];
 // 归档
 [array writeToFile:path3 atomically:YES];
 // 解档
 NSArray *array = [NSArray arrayWithContentsOfFile:path3];

2.NSUserDefault

用于保存一些程序配置信息
NSString *passWord = @"88888888";
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user setObject:passWord forKey:@"passWord"];

// 通过存储时候key取出相应的value
NSString *passWord = [ user objectForKey:@"passWord"];

可学习:
https://www.cnblogs.com/silence-wzx/p/5143113.html

3. NSKeyedArchiver归档解档

  • 将一个Objective-C对象转换成NSData的操作叫做对象的序列化;
  • 而将一个NSData转换成Objective-C对象的操作叫做对象的反序列化。
  • 一个Objective-C对象需要通过实现NSCoding协议以便支持序列化与反序列化

二.NSKeyedArchiver归档解档

需求:
有一个Person,需要对其属性进行赋值,可以存储到本地,也可以从本地读取。

Person类:
.h:
@interface Person : NSObject//实现协议才可使用NSKeyedArchiver归解档
//要归档的属性
//姓名
@property(nonatomic,strong)NSString * name;
//年龄
@property(nonatomic,assign)int age;
@end

.m:
@implementation Person

//进行归档
-(void)encodeWithCoder:(NSCoder *)aCoder{
    
   [aCoder encodeObject:self.name forKey:@"name"];
   [aCoder encodeInt:self.age forKey:@"age"];    
}

//进行解档
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
    
    if ([super init]) {  
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntForKey:@"age"];
    }
    return self;
}
@end
controller里面,对person赋值、存取:

- (void)viewDidLoad {
    [super viewDidLoad];    
    //给person对象赋值
    Person * person = [[Person alloc] init];
    person.name = @"lyttt";
    person.age = 18;
    
    NSString * tempPath = NSTemporaryDirectory();
    tempPath = [tempPath stringByAppendingString:@"/personInfo1.data"];
    
    //存数据
    [self savePersonInfo:person path:tempPath];
    //取出数据
    [self readPersonInfoWithPath:tempPath];
    
}
//存数据
-(void)savePersonInfo:(Person *)person path:(NSString *)path{
   BOOL saveResult = [NSKeyedArchiver archiveRootObject:person toFile:path];
   NSLog(@"保存是否成功:%d",saveResult);
}
//取数据
-(void)readPersonInfoWithPath:(NSString *)path{
    Person * getPerson = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    NSLog(@"person name:%@,person age:%d",getPerson.name,getPerson.age);
}

上面的代码就可以实现归档解档,如果Person里面有10多个、20多个属性的话,我们再person里面对每个属性归解档就太麻烦。我们就运用runtime的方法了。主要运用runtime可以读取所有属性的方法。
如下:

//进行归档
-(void)encodeWithCoder:(NSCoder *)aCoder{

//    [aCoder encodeObject:self.name forKey:@"name"];
//    [aCoder encodeInt:self.age forKey:@"age"];

    //使用runtime进行归档
    unsigned int outCount = 0;
    Ivar * ivars = class_copyIvarList([self class], &outCount);
    for (int i = 0; i < outCount; i++) {
        
        const char * varCharName = ivar_getName(ivars[i]);
        NSString * varName = [NSString stringWithFormat:@"%s",varCharName];
        [aCoder encodeObject:[self valueForKey:varName] forKey:varName];
    }
    
}
//进行解档
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
    
    if ([super init]) {
        
//        self.name = [aDecoder decodeObjectForKey:@"name"];
//        self.age = [aDecoder decodeIntForKey:@"age"];
        
        //使用runtime进行解档
        unsigned int outCount = 0;
        Ivar * ivars = class_copyIvarList([self class], &outCount);
        for (int i = 0; i < outCount; i++) {
            
            const char * varCharName = ivar_getName(ivars[i]);
            NSString * varName = [NSString stringWithFormat:@"%s",varCharName];
            
            [self setValue:[aDecoder decodeObjectForKey:varName] forKey:varName];
            
        }
    }
    return self;
    
}

c语言里面:函数参数如果是基本数据类的指针,基本上是需要在内部修改它的值。例如在归档解档时候的outCount值,原本是0,传入的是指针,再获取outCount值的时候已经是属性的个数。

你可能感兴趣的:(Runtime实例运用-归档解档)