美文网首页
ios 归档和解归档(利用runtime)

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

作者: HRSLN | 来源:发表于2017-03-06 09:03 被阅读196次

    前言

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

    iOS的几种数据持久化方案

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

    自定义类归与解档

    1.需要实现<NSCoding>代理方法
    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)

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