NSCoding和NSSecureCoding

5,597 阅读3分钟

NSCoding

NSCoding is a protcol that you can implement on your data classes to support encoding and decoding your data into a data buffer, which can then be persisted to disk.

如果想把自定义的对象持久化(存到硬盘),或者用于网络传输。需要先将自定义对象序列化成NSData

如果自定义对象要想转成NSData,需要服从NSCoding协议。并实现其中的两个方法。

NSSecureCoding

iOS6中,苹果引入了一个新的协议,是基于NSCoding的,叫做NSSecureCoding。NSSecureCoding和NSCoding是一样的,除了在解码时要同时指定key和要解码的对象的类,如果要求的类和从文件中解码出的对象的类不匹配,NSCoder会抛出异常,告诉你数据已经被篡改了。
大部分支持NSCoding的系统对象都已经升级到支持NSSecureCoding了

持久化

持久化三个常见方法

  1. plist
  2. NSUserDefault
  3. 数据库

不管是哪一种方案,都不可能直接存储用户自定义的对象,所以需要将自定义的对象序列化成NSData,才能持久化。

需要用到的时候,就用数据库中取出,然后反序列化,恢复成对象

Demo

// Foo.h
@interface Foo : NSObject <NSSecureCoding>

@property (nonatomic, copy) NSString *bar;
@property (nonatomic, assign) float baz;

@end
// Foo.m
#import "Foo.h"

static NSString * const kBar = @"kBar";
static NSString * const kBaz = @"kBaz";

@implementation Foo

- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
    [aCoder encodeObject:_bar forKey:kBar];
    [aCoder encodeFloat:_baz forKey:kBaz];
}

- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
    if (self = [super init]) {
        self.bar = [aDecoder decodeObjectForKey:kBar];
        self.baz = [aDecoder decodeFloatForKey:kBaz];
    }
    return self;
}

+ (BOOL)supportsSecureCoding
{
    return YES;
}

-(NSString *)description{
    return [NSString stringWithFormat:@"bar:%@ ; baz:%f",self.bar, self.baz];
}

@end
    Foo *foo = [[Foo alloc] init];
    foo.bar = @"祈求者Kael";
    foo.baz = 24;
    
    NSError *error0;
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:foo requiringSecureCoding:YES error:&error0];
    NSLog(@"data --- %@", data);
    
    NSError *error1;
    Foo *foo1 = [NSKeyedUnarchiver unarchivedObjectOfClass:[Foo class] fromData:data error:&error1];
    NSLog(@"foo1 = %@", foo1);
2019-05-23 20:28:06.252195+0800 NSCodingDemo[1081:41952] data --- <62706c69 73743030 d4010203 04050616 17582476 65727369 6f6e5824 6f626a65 63747359 24617263 68697665 72542474 6f701200 0186a0a4 07080f10 55246e75 6c6cd309 0a0b0c0d 0e546b42 6172546b 42617a56 24636c61 73738002 2241c000 00800367 79486c42 8005004b 00610065 006cd211 1213145a 24636c61 73736e61 6d655824 636c6173 73657353 466f6fa2 1315584e 534f626a 6563745f 100f4e53 4b657965 64417263 68697665 72d11819 54726f6f 74800108 111a232d 32373c42 494e535a 5c616372 77828b8f 929badb0 b5000000 00000001 01000000 00000000 1a000000 00000000 00000000 00000000 b7>
2019-05-23 20:28:06.252538+0800 NSCodingDemo[1081:41952] foo1 = bar:祈求者Kael ; baz:24.000000