我在 NSCoding 方面遇到了一些麻烦,我有这个简单的“Grade”类:
@interface Grade : NSObject<NSCoding>
@property (copy) NSString *name;
@property NSInteger grade;
@end
它实现了NSCoding,如下所示:
-(void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.name forKey:@"name"];
[coder encodeInt64:self.grade forKey:@"grade"];
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if(self)
{
self.name = [coder decodeObjectForKey:@"name"];
self.grade = [coder decodeInt64ForKey:@"grade"];
}
return self;
}
我有一个包含这些对象的 NSMutableArray,我将其放入存档中,如下所示:
NSArray<Grades*> *array = [NSArray arrayWithArray:self.tableContents];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: array requiringSecureCoding:NO error: nil];
NSLog(@"archived data: %@", data);
这工作正常,但问题是当我尝试从此存档中提取时:
NSError *error = nil;
NSArray *arrayFromData = [NSKeyedUnarchiver unarchivedObjectOfClass:[NSArray class] fromData:data error:&error];
我不断收到错误:'NSCocoaErrorDomain - 代码:4864' 在我的 NSError 变量中,并且 NSKeyedUnarchiver 不断返回 nil。
我在这里做错了什么?
问题是
requiringSecureCoding:NO
。此时您必须使用安全编码。这意味着你必须让 Grade 采用 NSSecureCoding,而不是 NSCoding;并且您必须在解档时列出您打算在一组中解档的所有类。
所以,成绩:
@implementation Grade
+ (BOOL) supportsSecureCoding { return YES; }
- (instancetype)initWithName:(NSString*)name grade:(NSInteger)grade
{
self = [super init];
if(self) {
self.name = name;
self.grade = grade;
}
return self;
}
-(void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.name forKey:@"name"];
[coder encodeInt64:self.grade forKey:@"grade"];
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if(self)
{
self.name = [coder decodeObjectForKey:@"name"];
self.grade = [coder decodeInt64ForKey:@"grade"];
}
return self;
}
@end
现在,让我们创建一个 Grade 数组,将其存档,然后取消存档:
NSArray<Grade*> *array = @[
[[Grade alloc] initWithName: @"Matt" grade: 4],
];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject: array requiringSecureCoding:YES error: nil];
NSLog(@"archived data: %@", data);
NSError *error = nil;
NSSet *classesSet = [NSSet setWithObjects:[NSString class], [Grade class], [NSArray class], nil];
NSArray *arrayFromData = (NSArray*)[NSKeyedUnarchiver unarchivedObjectOfClasses: classesSet fromData: data error: &error];
NSLog(@"array: %@", arrayFromData);