什么是 NSCoding,NSCode
NSCoding 协议
NSCoding 协议是把数据存储在 iOS 和 MacOS 上的一种极其简单和方便的方式,它把模型对象直接转变成一个文件,然后再把这个文件重新加载到内存里。
实现2个方法:
- (void)encodeWithCoder:(NSCoder *)coder;
- (nullable instancetype)initWithCoder:(NSCoder *)coder; // NS_DESIGNATED_INITIALIZER
举例如下:
- (void)testArchive {
Person *p1 = [[Person alloc] init];
p1.name = @"张三";
p1.age = 10;
NSError *error;
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:p1 requiringSecureCoding:**NO** error:&error];
//本地拿出来 反序列化
Person *p2 = [NSKeyedUnarchiver unarchivedObjectOfClass:Person.class fromData:data error:&error];
NSLog(@"p2 = %@",p2.name);
}
运行后会有如下错误:
Error Domain=NSCocoaErrorDomain Code=4864 "This decoder will only decode classes that adopt NSSecureCoding. Class 'Person' does not adopt it." UserInfo={NSDebugDescription=This decoder will only decode classes that adopt NSSecureCoding. Class 'Person' does not adopt it.
NSSecureCoding 协议
是 NSCoding 的变种,因为 NSCoding 毕竟不太安全,大部分支持 NSCoding 的系统对象都已经升级到支持 NSSecureCoding 了。
NSCoding 安全性不高,存储到 rom 中会被篡改
NSSecureCoding 安全的,会进行类型检查,类型不匹配,就抛出异常。
// Objects which are safe to be encoded and decoded across privilege boundaries should adopt NSSecureCoding instead of NSCoding. Secure coders (those that respond YES to requiresSecureCoding) will only encode objects that adopt the NSSecureCoding protocol.
// NOTE: NSSecureCoding guarantees only that an archive contains the classes it claims. It makes no guarantees about the suitability for consumption by the receiver of the decoded content of the archive. Archived objects which may trigger code evaluation should be validated independently by the consumer of the objects to verify that no malicious code is executed (i.e. by checking key paths, selectors etc. specified in the archive).
@protocol NSSecureCoding <NSCoding>
// 另外实现
+ (BOOL)supportsSecureCoding{
return YES;//支持加密编码
}
NSCode
NSCoder是一个抽象类,抽象类不能被实例化,只能提供一些想让子类继承的方法。
下边两个就是其子类:
NSKeyedUnarchiver 从二进制流读取对象。
NSKeyedArchiver 把对象写到二进制流中去。
只有遵守了 NSCoding 协议的对象才可以被存储。
NSKeyedArchiver NSKeyedUnarchiver
NSKeyedArchiver、NSKeyedUnarchiver ,主要用在 iOS 数据存储上,数据从内存存储到闪存上,这个过程称为归档。Apple 官方文档中,这些数据类型包括:
NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。很显然,复杂数据例如 UIImage,无法直接归档。但我们有一种变通的做法,先将UIImage对象转换为 NSData,再对 NSData 进行归档。