我正在创建链接列表并使用容器对对象,下一个和以前的属性进行分组。像Foundation集合一样,我希望它能够实现NSSecureCoding
。这是宣言:
@interface ListContainer : NSObject <NSCopying, NSSecureCoding>
@property (readonly, nonatomic) id object;
@property (nonatomic) ListContainer * next;
@property (nonatomic) ListContainer * previous;
@end
当实现- initWithCoder:
方法时,我发现我不知道该对象使用哪个类:
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
_object = [aDecoder decodeObjectOfClass:<#(__unsafe_unretained Class)#> forKey:@"object"];
BOOL nextIsNil = [aDecoder decodeBoolForKey:@"nextIsNil"];
if (!nextIsNil) {
// Decode next
_next = [aDecoder decodeObjectOfClass:[ListContainer class] forKey:@"next"];
if (_next == nil) {
return nil;
}
// Link the nodes manually to prevent infinite recursion
self.next.previous = self;
}
}
return self;
}
我应该使用-decodeObjectForKey:
吗?它仍然是安全的编码吗?
答案 0 :(得分:1)
我最后向Cocoa的邮件列表发布了同样的问题,最有趣的讨论发生了。一些亮点:
[...]制作一个正常的NSArray,如NSString,NSNumber,编码 它,用decodeObjectForClasses解码它,没有类。你会 在阵列上失败。将NSArray添加到允许的类列表中 .. 有用。所以,你认为,NSArray会盲目地解码任何东西 它不再安全。
添加自定义类的对象 实现对阵列的安全编码,它将开始失败 再次。 NSArray和其他集合类型允许元素 已知的安全系统类型,如NSString,但在任何外部都失败 那。 [...]
此时我明白NSArray并不像我预期的那样行事。安全编码似乎不再那么安全:
这似乎远非理想[...]它解码了一组 已知实现NSSecureCoding的类是错误的,IMO,两个 原因[...]
1)包含的类实现NSSecureCoding 的事实 并不意味着我期待它。 [...]
2)它限制了可以存储的类。 [...]
获得一个我在替代攻击中没有预料到的课程尤其可怕。显然,可可的承诺是不同的:
[...]如果您直接使用NSArray()或其他集合类 你的编码,你需要检查你得到的东西。他们是 “安全”解码到Apple认为解码它们的程度 不会导致缓冲区溢出等,这就是你所能得到的 默认即可。 [...]
所以,不,NSSecureCoding
不保证容器的安全编码,或者至少它不保证类型检查,你必须自己做。甚至在我最初假设的Cocoa原生数据结构中也没有(有理由,我仍然认为)。
Props去Roland King做了很多努力。您可以看到完整的对话here。