1.介绍
在iOS的开发中,小数据量的持久化大多用NSUserDefaults来实现,但是NSUserDefaults只能保存NSString, NSNumber, NSDate, NSArray, NSDictionary, NSData这些数据类型。
但大多时候,我们会将一个对象实体做持久化的保存,由于不是大批量的数据,不会用到sqlite,那么这个时候NSUserDefaults会是很好的选择,此时就需要将对象类型转换成NSData或者文件来存储,对象序列化,需要通过NSCoding的委托方法来实现的。
2.代码
我们自定义一个类RACCodingDemo:
头文件:
#import <Foundation/Foundation.h>
@interface RACCodingDemo : NSObject <NSSecureCoding>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
实现文件:
#import "RACCodingDemo.h"
@implementation RACCodingDemo
- (instancetype)init{
if (self = [super init]) {
_name = @"xiaoming";
_age = 5;
}
return self;
}
+ (BOOL)supportsSecureCoding{
return YES;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
if (!aDecoder) {
return self;
}
// _name = [aDecoder decodeObjectForKey:@"name"];
_name = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"name"];
_age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInteger:_age forKey:@"age"];
}
@end
3.讲解
想要支持转换成NSData,需要继承NSSecureCoding或者NSCoding协议,最新的一般使用NSSecureCoding协议,继承此协议,需要完成几个方法:
+ (BOOL)supportsSecureCoding
- (instancetype)initWithCoder:(NSCoder *)aDecoder
- (void)encodeWithCoder:(NSCoder *)aCoder
supportsSecureCoding方法返回YES,表示支持加密Coding
encodeWithCoder用于编码,把每个成员的值,依次存入aCoder中
initWithCoder用于解码,从aDecoder获取每个成员的值
编码:
利用如下方式:
[aCoder encodeObject:_name forKey:@"name"];
将name属性,放入aCoder,并且设置键值
解码
利用如下方法:
_name = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"name"];
从aDecoder中获取对应键的值,因为NSSecureCoding协议更加安全,需要填入这个值的类型,防止数据被恶意篡改
4. GitHub
整个数据持久化操作的Demo代码,都存储在GitHub中
其中NSCoding操作的内容,在RACCodingDemo
类中