Pregunta

Estoy teniendo una excepción "doesNotRecognizeSelector" y sospecho que tal vez mi regreso Unarchiver gama inmutable intstead de mutable. Estoy en lo cierto? ¿Cómo debo hacer el archivo y el archivo correctamente? (Lugar de excepción es mostrar hacia abajo)

Gracias !!!

NSMutableArray* arr;

- (void) write
{
         NSMutableData *data = [[NSMutableData alloc] init];
         NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];

 NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] copy];
        [archiver encodeObject:copy forKey:@"Key"];
        [archiver finishEncoding];
        [data writeToFile:[Util DataPath] atomically:YES];
        [archiver release];
        [data release];
        [copyOfPaidPacks release];
}




-(NSMutableArray*) read
{
    NSString* DataPath = [Util FilePath];
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:DataPath];
    NSKeyedUnarchiver *unarchiver = nil;
    if (data != nil)
    {
            unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];

    if([self.Arr count] <= 0)
    {
        self.Arr = [unarchiver decodeObjectForKey:@"Key"];  
    }
}

[unarchiver finishDecoding];
[unarchiver release];
[data release];
    return self.arr
}

-(void)B
{
     [self write];
     NSMutableArray* SecondArr = [self read];
     [SecondArr sortUsingSelector:@selector(CompareDate:)]; - > `****THIS IS WHERE I GET THE EXCEPTION`
}
  • Editar

Agregar el método compare:

- (NSComparisonResult)CompareDate:(T*)p
{
    NSComparisonResult result = [self.changeDate compare:p.changeDate];
    if(result == NSOrderedDescending)
        result = NSOrderedAscending;
    else if(result == NSOrderedAscending)
        result = NSOrderedDescending;

    if(result == NSOrderedSame)
    {
        result = [self CompareName:p];
    }

    return result;
}
¿Fue útil?

Solución

NSKeyedUnarchiver en efecto, devuelve un NSArray inmutable. Si usted realmente desea conseguir un NSMutableArray, que había necesidad de llamar -mutableCopy en el valor de retorno de decodeObjectForKey:.

Este fragmento de código hace que me pregunte si realmente siquiera necesita una matriz mutable sin embargo. Parece que estás clasificación de la matriz que se obtiene de -read. ¿Por qué no acaba de llamar sortedArrayUsingSelector: en la inmutable NSArray lugar?

Otros consejos

Ya pasar una matriz inmutable al archivador, ¿por qué se puede esperar del Unarchiver para volver una mutable entonces?

Si desea una copia para ser mutable, a continuación, usted tiene que utilizar

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] mutableCopy];

como

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] copy];

creará una copia inmutable (al menos en lo que, como usted debe estar preocupado. En realidad el marco utilizará a menudo una representación interna mutable para casos inmutables, pero esto es un detalle de implementación y no se debe contar con ella, como estas representaciones han cambiado en el pasado y los documentos de cacao que decirle explícitamente, al no comprobar la representación interna).

EDIT: simplemente probado con NSKeyedArchiver mí mismo en IOS 5.0 simulador:

// this returns a mutable instance at runtime!
NSMutableArray* test0 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[NSMutableArray array]]];
// this returns an immutable instance at runtime!
NSArray* test1 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[NSArray array]]];

Así que su problema es realmente causado exclusivamente mediante el uso de copia en lugar de mutableCopy, al archivar y desarchivar mantiene las correctas mutabilidad-atributos de los casos!

I tenía un problema en el archivo de una matriz mutable 3 dimensiones (es decir, una matriz mutable de arrays mutables de arrays mutables) habría desarchivar como una matriz mutable de arrays inmutables de arrays inmutables.

La clave para la fijación de este era subclase NSKeyedUnarchiver y sobrescribir

- (Class)classForClassName:(NSString *)codedName
{
    Class theClass = [super classForClassName: codeName];

    if ([codeName isEqualToString: NSStringFromClass(NSArray.class))
    {
        theClass = NSMutableArray.class;
    }
    //... more here like NSDictionary
    return theClass;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top