English 中文(简体)
收集自定义类的 NNSCeure 编码问题
原标题:NSSecureCoding trouble with collections of custom class

我无法采用NSSsecureCoding 。 我编码了一个包含我自定义类别对象的阵列, 它正确采用了 < code> NSSecureCoding /code。 当我解码它, 通过该类 < code> NSAray (是我编码的对象的类别) 时, 它会扔出一个例外。 但是, 当 < em> 与字符串完全相同的东西 使用一系列字符串时, 它会工作正常。 我看不出我的班级和NSString有什么区别 。

#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;
}
问题回答

我的解决办法是使用 decodeObjectofClasses:forKey:

在斯威夫特:

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]

解码对象解码对象的更改解决了我的上述例外。

我在斯威夫特5号 花了一个小时 费尽心思想着这个

我的情况是,我有一套 定制的解决方案对象:

var resultsSet = Set<Solution>()

符合安全编码:

static var supportsSecureCoding: Bool{ get{ return true } }

由于安全编码,他们的集装箱物体将它们编码为NSSet:

aCoder.encode(resultsSet as NSSet, forKey: "resultsSet")

但我在解码时总是有一个 遵守者错误:

if let decodedResultsSet = aDecoder.decodeObject(of: NSSet.self, forKey: "resultsSet"){
    resultsSet = decodedResultsSet as! Set<Solution>
}

错误 :

2020-02-11 22:35:06.555015+1300 Exception occurred restoring state value for key NS.objects was of unexpected class App.Solution . Allowed classes are {( NSSet )} . 2020-02-11 22:35:06.564758+1300 *** Terminating app due to uncaught exception NSInvalidUnarchiveOperationException , reason: value for key NS.objects was of unexpected class App.Solution . Allowed classes are {( NSSet )} .

如果我更改了解码对象( 分类: 解答 :

if let decodedResultsSet = aDecoder.decodeObject(of: Solution.self, forKey: "resultsSet"){
    resultsSet = decodedResultsSet as! Set<Solution>
}

我知道错误:

2020-02-11 22:33:46.924580+1300 Exception occurred restoring state value for key resultsSet was of unexpected class NSSet . Allowed classes are {( app.Solution )} . 2020-02-11 22:33:46.933812+1300 *** Terminating app due to uncaught exception NSInvalidUnarchiveOperationException , reason: value for key resultsSet was of unexpected class NSSet . Allowed classes are {( app.Solution )} .

答案是显而易见的,现在, 但我可以找到它任何地方 是意识到允许对象列表是一个阵列, 它需要 NSSet 和定制对象:解决方案。

if let decodedResultsSet = aDecoder.decodeObject(of: [NSSet.self, Solution.self], forKey: "resultsSet"){
    resultsSet = decodedResultsSet as! Set<Solution>
}

I had the same problem in Swift with iOS 15 / Xcode 13.2. I solved it by simply adding NSNumber (the offending class listed in the warning) in the decoder.decodeObject of required init(coder decoder: NSCoder) { } (I edited the class names). MyVar contains some numbers.

required init(coder decoder: NSCoder) {
    
    myVar = decoder.decodeObject(of: [MyType.self, NSNumber.self], forKey: theKey) as? [MyVar] ?? []
}




相关问题
Asynchronous request to the server from background thread

I ve got the problem when I tried to do asynchronous requests to server from background thread. I ve never got results of those requests. Simple example which shows the problem: @protocol ...

objective-c: Calling a void function from another controller

i have a void, like -(void) doSomething in a specific controller. i can call it in this controller via [self doSomething], but i don t know how to call this void from another .m file. I want to call ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

NSUndoManager and runModalForWindow:

I have a simple Core Data app which displays a list of entities in the main window. To create or add new entities, I use a second modal window with a separate managed object context so changes can be ...

NSMutableArray values becoming "invalid"

I m trying to show a database information in a tableview and then the detailed information in a view my problem is as follow: I created a NSMutableArray: NSMutableArray *myArray = [[NSMutableArray ...

iPhone numberpad with decimal point

I am writing an iPhone application which requires the user to enter several values that may contain a decimal point (currency values, percentages etc.). The number of decimal places in the values ...

热门标签