iOS中使用runtime进行数据模型类的序列化和反序列化

2017-03-07  本文已影响58人  雷鸣1010

demo下载地址
在 iOS 中归档数据时,如果归档的是我们自定义的数据模型类,则需要我们手动进行序列化和反序列化才能进行归档.
在此,我们使用 runtime 进行序列化和反序列化,思路大致为:新建一个数据模型的基类,基类.h文件中不需要写任何属性, 然后在基类的.m文件中利用 runtime 进行序列化和反序列化,至此基类已经完成.此后如果我们工程中哪一个数据模型类需要进行归档存储,就可以直接继承前面的基类即可.也就是说继承基类的其它数据模型类无需再进行序列化和反序列化就可以进行归档数据.
不多说,开始做,上代码,以下是步骤:

1.新建数据模型基类WLNSObject

基类一定要遵守NSCoding协议.
.h文件如下:

#import <Foundation/Foundation.h>

@interface WLNSObject : NSObject<NSCoding>
@en

.m文件如下:

#import "WLNSObject.h"
#import <objc/runtime.h>

@implementation WLNSObject

//序列化
-(void)encodeWithCoder:(NSCoder *)aCoder{
    unsigned int ivarCount = 0;
    Ivar *ivars = class_copyIvarList([self class], &ivarCount);
    for (unsigned int i = 0; i < ivarCount; i++) {
        const char *ivar_name = ivar_getName(ivars[i]);
        NSString *key = [NSString stringWithCString:ivar_name encoding:NSUTF8StringEncoding];
        [aCoder encodeObject:[self valueForKey:key] forKey:key];
    }
}

//反序列化
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        unsigned int ivarCount = 0;
        Ivar *ivars = class_copyIvarList([self class], &ivarCount);
        for (unsigned int i = 0; i < ivarCount; i++) {
            const char *ivar_name = ivar_getName(ivars[i]);
            NSString *key = [NSString stringWithCString:ivar_name encoding:NSUTF8StringEncoding];
            [self setValue:[coder decodeObjectForKey:key] forKey:key];
        }
    }
    return self;
}

@end

2.新建继承基类WLNSObject的数据模型Man

Man的.h文件如下:

#import "WLNSObject.h"

@interface Man : WLNSObject
@property (nonatomic, strong) NSString *name;
@end

Man的.m文件中不需要任何操作,在这里就不列出了.

3.新建继承基类WLNSObject的数据模型Person

Person的.h文件如下:

#import <Foundation/Foundation.h>
#import "WLNSObject.h"
#import "Man.h"

@interface Person : WLNSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, strong) Man *friend;
@end

Person的.m文件中不需要任何操作,在这里就不列出了.

4.进行归档测试

在main.m中进行测试, 如下:

#import "ViewController.h"
#import "Man.h"
#import "Person.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    Person *obj = [[Person alloc] init];
    obj.name = @"Jack";
    obj.age = 27;
    
    obj.friend = [[Man alloc] init];
    obj.friend.name = @"Tom";
    
    //归档
    [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:obj] forKey:@"myObj"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    //反归档
    Person *p = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] dataForKey:@"myObj"]];
    
    NSLog(@"p.name:%@, p.age:%lu, p.friend.name = %@", p.name, p.age, p.friend.name);

}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

输出结果如下:

2017-03-07 23:27:08.119 NSCodingDemo[14355:781208] p.name:Jack, p.age:27, p.friend.name = Tom

至此,我们所有继承基类WLNSObject的数据模型无需再进行序列化和反序列化就可以进行归档数据了.

转发自:http://www.jianshu.com/p/b156040307c3

上一篇下一篇

猜你喜欢

热点阅读