NSKEYEDARCHIVER FILE - Perder dados
-
23-09-2019 - |
Pergunta
Usando o iPhone SDK 3.1.2. Estou economizando algumas informações em um arquivo usando NSKeyedArchiver
objeto. Eu tenho 4 chaves. Eu li dados do arquivo para todas as 4 chaves em applicationDidFinshLaunching
e escreva de volta ao arquivo (todas as 4 chaves) em applicationDidTerminate
. Além disso, quando o usuário salva qualquer informação, escrevo os dados para a chave específica é para.
Caso não haja arquivo inicialmente, alquei uma matriz para a lista de conta, isso me permite adicionar contas a ele.
Estou tendo problemas com o arquivo perdendo periodicamente os dados salvos. Às vezes é uma das principais listas de conta afetadas pelo IE, às vezes é a lista de favoritos. Parece ser exacerbado se eu economizar apenas 1key em oposição a todos os 4. Visei o arquivo usando o Organsier e, de fato, os dados estão faltando. O problema é muitas vezes que não funciona. Eu não, por que é tão inconsistente. Além disso, se eu termontate o depurador no Xcode, esperaria perder apenas alterações recentes, não os dados inteiros que os dados parecem acontecer. Toda a coisa de Nskeyedchiver parece tão flakey que estou considerando talvez outra estratégia de armazenamento persistente. Qualquer pessoa se depara com algo assim.
- (void)viewDidLoad
{
if( self.accountList == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
self.accountList = array;
[array release];
}
if( self.phoneSettings == nil)
{
PhoneSettings* mySettings = [[PhoneSettings alloc] initSettings];
self.phoneSettings = mySettings;
[mySettings release];
}
NSString *filePath = [self dataFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSData *data = [[NSMutableData alloc]
initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
NSMutableArray *archiveArray = [unarchiver decodeObjectForKey:kDataKey];
if(archiveArray != nil)
self.accountList = [archiveArray retain];
else
LOG("No archived accounts" );
NSMutableArray *archiveCallList = [unarchiver decodeObjectForKey:kCallListKey];
if(archiveCallList !=nil)
appDelegate.callList = [archiveCallList retain];
NSMutableArray *archiveFavouritesList = [unarchiver decodeObjectForKey:kfavouritesKey];
if(archiveFavouritesList != nil)
appDelegate.favouritesList = [archiveFavouritesList retain];
PhoneSettings* archiveSettings = [unarchiver decodeObjectForKey:kPhoneSettings];
if (archiveSettings != nil)
self.phoneSettings = [archiveSettings retain];
[unarchiver finishDecoding];
[unarchiver release];
[data release];
}
então em
- (void)applicationWillTerminate:(NSNotification *)notification {
LOG("Application terminating");
SessionTalkAppDelegate* appDelegate = (SessionTalkAppDelegate*)[[UIApplication sharedApplication] delegate];
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data];
[archiver encodeObject:self.accountList forKey:kDataKey];
[archiver encodeObject:appDelegate.callList forKey:kCallListKey];
[archiver encodeObject:appDelegate.favouritesList forKey:kfavouritesKey];
[archiver encodeObject:self.phoneSettings forKey:kPhoneSettings];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES];
[archiver release];
[data release];
}
Solução
Você não precisa muito código. Salve seus dados:
NSMutableDictionary *appState = [NSMutableDictionary dictionary];
[appState setObject: self.accountList forKey: kDataKey];
[appState setObject: appDelegate.callList forKey: kCallListKey];
[appState setObject: self.phoneSettings forKey: kPhoneSettings];
if ( [NSKeyedArchiver archiveRootObject: appState toFile: [self dataFilePath]] == NO )
NSLog(@"Failed to archive %@", appState);
Leia os dados:
NSMutableDictionary *appState = [NSKeyedUnarchiver unarchiveObjectWithFile: [self dataFilePath]];
Observe que o NSKEYEDUNCHIVER pode aumentar uma NSInValIDARGumGentException se o arquivo não contiver um arquivo válido; portanto, você deve incluir a chamada em um bloco @try {}.