ios 归档和解归档(利用runtime)

前言

iOS存取数据的方式有几种,这次项目中存储一些小数据所以用的归档,希望对用归档存储数据的同学有帮助。

iOS的几种数据持久化方案

  • NSKeyedArchiver(归档)
  • preference(偏好设置)
  • plist文件
  • SQLite
  • CoreData

自定义类归与解档

1.需要实现代理方法
2.需要实现的方法

- (instancetype)initWithCoder:(NSCoder *)coder
- (void) encodeWithCoder: (NSCoder *)coder

利用runtime获得所有属性

- (NSArray *)getAllProperty {
    NSMutableArray *array = [[NSMutableArray alloc]init];
    unsigned int *count = malloc(sizeof(unsigned int));
    //调用runtime方法
    //Ivar:方法返回的对象内容对象,这里将返回一个Ivar类型的指针
    //class_copyIvarList 方法可以捕获到类的所有变量 将变量的数量存在一个 unsigned int指针中
    Ivar *mem = class_copyIvarList([self class], count);
    for (int i = 0; i < *count; i++) {
        //通过移动指针进行遍历
        Ivar var = * (mem + i);
        //获取变量的名称
        const char *name = ivar_getName(var);
        NSString *varStr = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
        [array addObject:varStr];
    }
    //释放内存
    free(count);
    //注意处理野指针
    count = nil;
    return array;
}
  • initWithCoder
- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super init]) {
        //获取所有属性
        NSArray *porpertyArray = [self getAllProperty];
        for (NSString *name in porpertyArray) {
            //去掉属性名前面的_
            NSString *key = [name substringFromIndex:1];
            //设置约定的键值对 c+key
            [self setValue:[coder decodeObjectForKey:[NSString stringWithFormat:@"c%@",key]] forKey:key];
        }
    }
    return self;
}
  • encodeWithCoder
- (void)encodeWithCoder:(NSCoder *)coder {
    //获取所有属性
    NSArray *porpertyArray = [self getAllProperty];
    for (NSString *name in porpertyArray) {
        //去掉属性名前面的_
        NSString *key = [name substringFromIndex:1];
        //设置约定的键值对 c+key
        [coder encodeObject:[self valueForKey:key] forKey:[NSString stringWithFormat:@"c%@",key]];
    }
}

3.存储数据

  • 自定义一个方法存储数据
/**
 存储数据

 @param OAuth 需要储存的对象

 @return 是否储存成功
 */
+ (BOOL)saveOAuth:(OAuth *)OAuth;
  • 方法实现
+ (BOOL)saveOAuth:(OAuth *)OAuth {
    //获取doc的目录
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //拼接保存的路径
    NSString *filePath = [docPath stringByAppendingPathComponent:oauthPath];
    //存储返回用户信息
    return [NSKeyedArchiver archiveRootObject:OAuth toFile:filePath];
}

4.获取存储对象

  • 自定义定义方法
/**
 @return 获取存储对象
 */
+ (OAuth *)OAuth;
  • 实现方法
+ (OAuth *)OAuth {
    //获取doc的目录
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //拼接保存的路径
    NSString *filePath = [docPath stringByAppendingPathComponent:oauthPath];
    //获取用户存储的授权信息
    OAuth *oAuth = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    if (!oAuth) {
        oAuth = [[OAuth alloc]init];
    }
    return oAuth;
}

5.删除所有归档

  • 自定义方法
/**
 删除所有归档
 */
+ (void)logOut;
  • 实现方法
+ (void)logOut {
    //获取doc的目录
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //拼接保存的路径
    NSString *filePath = [docPath stringByAppendingPathComponent:oauthPath];
    //删除路径.data文件
    NSFileManager *fileManage = [NSFileManager defaultManager];
    [fileManage removeItemAtPath:filePath error:nil];
}

总结

以上是我用归档存储数据的代码。
github

你可能感兴趣的:(ios 归档和解归档(利用runtime))