2011-09-26 10 views
6

Immagino che questo sia molto ovvio, ma ho una domanda sul caricamento dei dati. Se hai un file chiamato library.dat che memorizza tutti i tipi di informazioni sugli oggetti nell'app. È impostato in modo molto gradevole (in termini dei metodi initWithCoder e encodeWithCoder ecc.), Ma mi stavo chiedendo cosa succederebbe se il file library.dat venisse mai danneggiato. L'ho corrotto un po 'e l'app andrà in crash. C'è un modo per prevenire un incidente? Posso testare un file prima di caricarlo? Qui è il bit, che può potenzialmente essere molto fatale:NSKeyedUnarchiver - come prevenire un crash

-(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]; 



} 

ho dato un'occhiata al * NSInvalidUnarchiveOperationException ma non hanno idea di come dovrei implementare questo nel mio codice. Sarei grato per qualsiasi esempio. Grazie in anticipo!

risposta

13

È possibile eseguire il wrap della chiamata di annullamento con @try {} @ catch {} @ infine. Questo è descritto nei documenti Apple qui: 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

Grazie mille per aver confermato che questo è il modo ufficiale per gestirlo. –

+1

NSInvalidUnarchiveOperationException è una stringa, non una classe di eccezione. Quindi penso che devi prendere NSException, quindi controllare il suo nome ...? –

4

Hai provato i blocchi "try/catch"? Qualcosa del genere:

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

Grazie! Sono abbastanza nuovo a questo e la gente ha sempre messo in guardia contro i blocchi 'try/catch'. Sembra molto ragionevole in questo caso, però. Immagino che non ci sia altro modo se non quello di lavorare con i blocchi, giusto? –

+1

Penso che non ci siano altre soluzioni semplici. Purtroppo. – igoris

+0

Ho appena provato questo, ma xCode mi dice che "Nome tipo sconosciuto 'NSInvalidUnarchiveOperationException'" - devo definirlo in precedenza? –