2011-09-26 15 views
6

Supongo que esto es muy obvio, pero tengo una pregunta sobre la carga de datos. Si tiene un archivo llamado library.dat que almacena todo tipo de información sobre objetos en la aplicación. Está configurado todo muy bien (en términos de los métodos initWithCoder y encodeWithCoder, etc.), pero me preguntaba qué pasaría si el archivo library.dat se corrompe alguna vez. Lo corrompí un poco y la aplicación se bloqueará. ¿Hay alguna forma de prevenir un bloqueo? ¿Puedo probar un archivo antes de cargarlo? Aquí es el bit que potencialmente puede ser muy grave:NSKeyedUnarchiver: cómo evitar un bloqueo

-(void)loadLibraryDat { 

    NSLog(@"loadLibraryDat..."); 
    NSString *filePath = [[self documentsDirectory] stringByAppendingPathComponent:@"library.dat"]; 

    // if the app crashes here, there is no way for the user to get the app running- except by deleting and re-installing it... 
    self.libraryDat = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 



} 

tuve un vistazo a * NSInvalidUnarchiveOperationException pero no tienen idea de cómo debería implementar esto en mi código. Agradecería cualquier ejemplo. ¡Gracias por adelantado!

Respuesta

13

se puede envolver la llamada desarchivar con @try {} catch {@} @ finalmente. Esto se describe en la documentación de Apple aquí: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/ObjectiveC/Chapters/ocExceptionHandling.html

@try { 
    self.libraryDat = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 
} @catch (NSInvalidUnarchiveOperationException *ex) { 
    //do whatever you need to in case of a crash 
} @finally { 
    //this will always get called even if there is an exception 
} 
+3

Muchas gracias por confirmar que esta es la forma oficial de manejar esto. –

+1

NSInvalidUnarchiveOperationException es una cadena, no una clase de Excepción. ¿Entonces creo que tienes que atrapar NSException, luego verificas su nombre ...? –

4

¿Has probado los bloques 'try/catch'? Algo como esto:

@try { 
    self.libraryDat = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 
} 
@catch (NSException* exception) { 
    NSLog(@"provide some logs here"); 
    // delete corrupted archive 
    // initialize libraryDat from scratch 
} 
+0

Gracias! Soy bastante nuevo en esto y la gente siempre advirtió contra los bloques 'try/catch'. Suena muy razonable en este caso, sin embargo. Supongo que no hay otro camino más que trabajar con bloques, ¿verdad? –

+1

Creo que no hay otras soluciones simples. Desafortunadamente. – igoris

+0

Acabo de probar esto, pero xCode me dice que "Nombre de tipo desconocido 'NSInvalidUnarchiveOperationException'" - ¿Tengo que definirlo previamente? –

Cuestiones relacionadas