Extraño comportamiento al decodificar un NSArray a través de NSSecureCoding

pasé toda la tarde golpeando la cabeza contra la panetworking tratando de descubrir por qué fallaba la deencoding de esta class. la class tiene una propiedad que es un NSArray de objects Foo. Foo cumple con NSSecureCoding, y he codificado y decodificado esa class por sí mismo. Estaba recibiendo un error en initWithCoder: dicho falló para descifrar la class Foo. a través de alguna experimentación, descubrí que necesitaba agregar [class Foo] a initWithCoder: para que funcione. tal vez esto ayude a otra persona que tenga el mismo problema. mi pregunta es: ¿por qué es necesario? No encontré ninguna sugerencia de que esto sea necesario en la documentation de Apple.

#import "Foo.h" @interface MyClass : NSObject <NSSecureCoding> @property (nonatomic) NSArray *bunchOfFoos; @end @implementation MyClass static NSString *kKeyFoo = @"kKeyFoo"; + (BOOL) supportsSecureCoding { return YES; } - (void) encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.bunchOfFoos forKey:kKeyFoo]; } - (id) initWithCoder:(NSCoder *)decoder { if (self = [super init]) { [Foo class]; // Without this, decoding fails _bunchOfFoos = [decoder decodeObjectOfClass:[NSArray class] forKey:kKeyFoo]; } return self; } @end 

Acabo de encontrar un problema similar y eso fue extraño y extremadamente lento. Quería probar que mi class es NSSecureCoded correctamente con Specta / Expecta . Por eso, he implementado todo lo que necesito especificando la class cuando se decodifica. Al final de mis ensayos obtuve la exception más extraña:

 value for key 'key' was of unexpected class 'MyClass'. Allowed classes are '{( MyClass )}'. 

La testing parecía algo así:

 MyClass *myClassInstance = ... NSMutableData *data = [NSMutableData data]; NSKeyedArchiver *secureEncoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; [secureEncoder setRequiresSecureCoding:YES]; // just to ensure things NSString *key = @"key"; [secureEncoder encodeObject:myClassInstance forKey:key]; [secureEncoder finishEncoding]; NSKeyedUnarchiver *secureDecoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; [secureDecoder setRequiresSecureCoding:YES]; MyClass *decodedInstance = [secureDecoder decodeObjectOfClass:[MyClass class] forKey:key]; // exception here [secureDecoder finishDecoding]; ...expect... 

Si bien la testing simple NSCoding (requiresSecureCoding = NO) tuvo éxito, las testings NSSecureCoding continuaron fallando. Después de una amplia gama de ensayos, encontré una solución para eso, solo una línea:

 [secureDecoder setClass:[MyClass class] forClassName:NSStringFromClass([MyClass class])]; 

Después de que todas mis testings tuvieron éxito, los objects se crearon como se esperaba.

No estoy seguro de por qué sucedió eso, supongo que sería que la class no es visible como sugirió Ben H y usa algo como NSClassFromString(@"MyClass") . El código anterior funcionó bien en AppDelegate. MyClass era de las vainas de desarrollo que estoy desarrollando.

Creo que podría haber imaginado esto. sin la línea [class Foo], no hay reference a la class Foo en este file. debido a esto, creo que el comstackdor está optimizando la class Foo, y luego los objects Foo dentro de la matriz no pueden decodificarse. Tener [class Foo] allí impide esto.

Para aquellos que todavía están luchando con esto. Literalmente paso un par de horas golpeando mi cabeza contra la panetworking también. La solución de @Ben H no resolvió mi problema. Y sigo teniendo el siguiente post de error:

La aplicación de finalización debido a la exception no detectada 'NSInvalidUnarchiveOperationException', razón:> 'valor para la key' NS.objects 'era de class inesperada' ClassA '. Las classs permitidas son '{(
NSArray
)} '.'

Y finalmente, me di count de que para las classs personalizadas. En lugar de decodeObjectOfClasses debe usar la siguiente function decodeObjectOfClasses :

 - (id)decodeObjectOfClasses:(NSSet *)classes forKey:(NSString *)key 

¡Y usted para pasar un NSSet de todas las classs posibles en el NSArray a la function anterior! No estoy seguro de por qué @Ben H podría resolver el problema simplemente agregando una [Foo class] fuera de la function. Quizás sea un problema del comstackdor. Pero de todos modos, si su solución no funciona. Prueba esta también. Dios te bendiga ~