首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义类集合的NSSecureCoding问题

自定义类集合的NSSecureCoding问题
EN

Stack Overflow用户
提问于 2014-06-24 00:49:12
回答 3查看 9.2K关注 0票数 15

我在采用NSSecureCoding时遇到了麻烦。我对包含自定义类对象的数组进行了编码,该数组正确地采用了NSSecureCoding。当我解码它,传递类NSArray (它是我编码的对象的类)时,它会抛出一个异常。但是,当对字符串数组执行完全相同的操作时,它工作得很好。我不明白我的课和NSString之间有什么区别。

代码语言:javascript
复制
#import <Foundation/Foundation.h>

@interface Foo : NSObject <NSSecureCoding>
@end
@implementation Foo
- (id)initWithCoder:(NSCoder *)aDecoder {
  return [super init];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
}
+ (BOOL)supportsSecureCoding {
  return YES;
}
@end

int main() {
  @autoreleasepool {

    NSMutableData* data = [[NSMutableData alloc] init];
    NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:@[[Foo new]] forKey:@"foo"];
    [archiver encodeObject:@[@"bar"] forKey:@"bar"];
    [archiver finishEncoding];

    NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    unarchiver.requiresSecureCoding = YES;
    // throws exception: 'value for key 'NS.objects' was of unexpected class 'Foo'. Allowed classes are '{( NSArray )}'.'
    [unarchiver decodeObjectOfClass:[NSArray class] forKey:@"foo"];
    // but this line works fine:
    [unarchiver decodeObjectOfClass:[NSArray class] forKey:@"bar"];
    [unarchiver finishDecoding];

  }
  return 0;
}
EN

回答 3

Stack Overflow用户

发布于 2014-11-10 03:13:43

你可能已经解决了这个问题,但我刚刚找到了一个解决方案,我想我会把它留给其他发现这个的人。

我的解决方案是使用decodeObjectOfClasses:forKey:

迅速:

代码语言:javascript
复制
    if let data = defaults.objectForKey(FinderSyncKey) as? NSData
        let unArchiver = NSKeyedUnarchiver(forReadingWithData: data)
        unArchiver.setRequiresSecureCoding(true)
         //This line is most likely not needed, I was decoding the same object across modules
        unArchiver.setClass(CustomClass.classForCoder(), forClassName: "parentModule.CustomClass")
        let allowedClasses = NSSet(objects: NSArray.classForCoder(),CustomClass.classForCoder())
        if let unarchived = unArchiver.decodeObjectOfClasses(allowedClasses, forKey:NSKeyedArchiveRootObjectKey) as?  [CustomClass]{
            return unarchived

        }    
    }

在目标C中,它将类似于[unArchiver decodeObjectOfClasses:allowedClasses forKey:NSKeyedArchiveRootObjectKey]

将解码对象更改为解码对象为我解决了上述异常。

票数 17
EN

Stack Overflow用户

发布于 2020-02-11 10:08:00

我在斯威夫特5中挣扎了一个小时。

我的情况是我有一组自定义的解决方案对象:

代码语言:javascript
复制
var resultsSet = Set<Solution>()

符合安全编码的:

代码语言:javascript
复制
static var supportsSecureCoding: Bool{ get{ return true } }

由于安全编码,它们的容器对象将它们编码为NSSet:

代码语言:javascript
复制
aCoder.encode(resultsSet as NSSet, forKey: "resultsSet")

但我在解码过程中总是出现了一个编辑错误:

代码语言:javascript
复制
if let decodedResultsSet = aDecoder.decodeObject(of: NSSet.self, forKey: "resultsSet"){

            resultsSet = decodedResultsSet as! Set<Solution>
        }

错误:

202-02-11 22:35:06.555015+1300异常发生,因为键'NS.objects‘的状态值是意外的,类’Apps.卷积‘。允许的类是“{( NSSet )}”。2020年-02-11 22:35:06.564758+1300 *终止应用程序由于非正常异常'NSInvalidUnarchiveOperationException',原因:‘NS.objects键的值’是意外的类‘Apps.卷积’。允许的类是“{( NSSet )}”。

如果我更改了decodeObject(ofClass: to解决方案):

代码语言:javascript
复制
if let decodedResultsSet = aDecoder.decodeObject(of: Solution.self, forKey: "resultsSet"){

            resultsSet = decodedResultsSet as! Set<Solution>
        }

我知道错误:

202-02-11 22:33:46.924580+1300异常发生,因为键'resultsSet‘是意外类'NSSet’的状态值。允许的类是“{( app.Solution )}”。2020年-02-11 22:33:46.933812+1300 *终止应用程序由于未被异常“NSInvalidUnarchiveOperationException”,原因:‘resultsSet键的值’是意外类'NSSet‘。允许的类是“{( app.Solution )}”。

答案现在很明显,但我可以在任何地方找到,那就是实现允许的对象列表是一个数组,它同时需要NSSet和自定义对象:解决方案。

代码语言:javascript
复制
if let decodedResultsSet = aDecoder.decodeObject(of: [NSSet.self, Solution.self], forKey: "resultsSet"){

            resultsSet = decodedResultsSet as! Set<Solution>
        }

我希望这能帮上忙。

票数 8
EN

Stack Overflow用户

发布于 2022-02-02 21:25:07

在Swift中,iOS 15 / Xcode 13.2也出现了同样的问题。我通过简单地将NSNumber (警告中列出的违规类)添加到所需init的decoder.decodeObject (编码器解码器: NSCoder) {}(我编辑了类名)来解决这个问题。MyVar包含一些数字。

代码语言:javascript
复制
required init(coder decoder: NSCoder) {
    
    myVar = decoder.decodeObject(of: [MyType.self, NSNumber.self], forKey: theKey) as? [MyVar] ?? []
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24376746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档