demo下載地址
在 iOS 中歸檔數(shù)據(jù)時(shí),如果歸檔的是我們自定義的數(shù)據(jù)模型類,則需要我們手動(dòng)進(jìn)行序列化和反序列化才能進(jìn)行歸檔.
在此,我們使用 runtime 進(jìn)行序列化和反序列化,思路大致為:新建一個(gè)數(shù)據(jù)模型的基類,基類.h文件中不需要寫任何屬性, 然后在基類的.m文件中利用 runtime 進(jìn)行序列化和反序列化,至此基類已經(jīng)完成.此后如果我們工程中哪一個(gè)數(shù)據(jù)模型類需要進(jìn)行歸檔存儲(chǔ),就可以直接繼承前面的基類即可.也就是說繼承基類的其它數(shù)據(jù)模型類無需再進(jìn)行序列化和反序列化就可以進(jìn)行歸檔數(shù)據(jù).
不多說,開始做,上代碼,以下是步驟:
1.新建數(shù)據(jù)模型基類WLNSObject
基類一定要遵守NSCoding協(xié)議.
.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的數(shù)據(jù)模型Man
Man的.h文件如下:
#import "WLNSObject.h"
@interface Man : WLNSObject
@property (nonatomic, strong) NSString *name;
@end
Man的.m文件中不需要任何操作,在這里就不列出了.
3.新建繼承基類WLNSObject的數(shù)據(jù)模型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.進(jìn)行歸檔測(cè)試
在main.m中進(jìn)行測(cè)試, 如下:
#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
輸出結(jié)果如下:
2017-03-07 23:27:08.119 NSCodingDemo[14355:781208] p.name:Jack, p.age:27, p.friend.name = Tom
至此,我們所有繼承基類WLNSObject的數(shù)據(jù)模型無需再進(jìn)行序列化和反序列化就可以進(jìn)行歸檔數(shù)據(jù)了.
轉(zhuǎn)發(fā)自:http://www.reibang.com/p/b156040307c3