DecodeoDobjectFokey: restituisce sempre NIL
-
12-11-2019 - |
Domanda
Sto cercando di salvare il mio grafico dell'oggetto in un file e quindi ricaricarlo in un secondo momento, tuttavia Decodeobjectforkey: restituisce sempre NIL per qualsiasi tasto specificato.
Un file binario viene creato e ha il testo occasionale dell'uomo leggibile in esso, I.e., TitletextColor, quindi penso che il processo di archiviazione funzioni.
Ho perso-capito come il nskeyacherchiver e il nskeyedunarchiver funzionano?Qualsiasi aiuto sarebbe apprezzato.
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeFloat:titleFontSize forKey:@"titleFontSize"];
[encoder encodeObject:[UIColor orangeColor] forKey:@"titleTextColor"];
[encoder encodeObject:lineSeparatorColor forKey:@"lineSeparatorColor"];
[encoder encodeObject:bodyTextColor forKey:@"bodyTextColor"];
[encoder encodeFloat:bodyTextFontSize forKey:@"bodyTextFontSize"];
[encoder encodeObject:backgroundColor forKey:@"backgroundColor"];
[encoder encodeObject:tintColor forKey:@"tintColor"];
[encoder encodeInteger:bodyTextAlignment forKey:@"bodyTextAlignment"];
[encoder encodeObject:@"Text" forKey:@"Text"];
}
+ (void) saveToFile {
// Get the shared instance
PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];
// Serialise the object
NSData *serializedObject = [NSKeyedArchiver archivedDataWithRootObject:sharedInstance];
// Get the path and filename of the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];
// Write the defaults to a file
if (serializedObject) [serializedObject writeToFile:pathAndFileName atomically:YES];
}
+ (void) loadFromFile {
// Get the shared instance
PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];
// Get the path and filename of the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];
NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
NSKeyedUnarchiver *defaults = [[NSKeyedUnarchiver alloc] initForReadingWithData:codedData];
// Set the properties of the shared instance
NSString *test = [defaults decodeObjectForKey:@"Text"];
NSLog (@"%@", test);
sharedInstance.titleTextColor = [defaults decodeObjectForKey:@"titleTextColor"];
[defaults release];
}
.
Modifica: Basato su consigli da DarkDust:
.
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.titleFontSize = [[aDecoder decodeObjectForKey:@"titleFontSize"] floatValue];
self.titleTextColor = [aDecoder decodeObjectForKey:@"titleTextColor"];
self.lineSeparatorColor = [aDecoder decodeObjectForKey:@"lineSeparatorColor"];
self.bodyTextColor = [aDecoder decodeObjectForKey:@"bodyTextColor"];
self.bodyTextFontSize = [[aDecoder decodeObjectForKey:@"bodyTextFontSize"] floatValue];
self.backgroundColor = [aDecoder decodeObjectForKey:@"backgroundColor"];
self.tintColor = [aDecoder decodeObjectForKey:@"tintColor"];
self.bodyTextAlignment = [[aDecoder decodeObjectForKey:@"bodyTextAlignment"] intValue];
}
return self;
}
e creazione di una nuova istanza solo per testare:
.
+ (void) loadFromFile {
// Get the shared instance
PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];
// Get the path and filename of the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];
NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
PSYDefaults *newInstance = [NSKeyedUnarchiver unarchiveObjectWithData:codedData];
sharedInstance.titleTextColor = newInstance.titleTextColor;
}
Modifica - Aggiornamento (necessario per codificare galleggianti e interni come nsnumbers)
.- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:[NSNumber numberWithFloat:titleFontSize] forKey:@"titleFontSize"];
[encoder encodeObject:titleTextColor forKey:@"titleTextColor"];
[encoder encodeObject:lineSeparatorColor forKey:@"lineSeparatorColor"];
[encoder encodeObject:bodyTextColor forKey:@"bodyTextColor"];
[encoder encodeObject:[NSNumber numberWithFloat:bodyTextFontSize] forKey:@"bodyTextFontSize"];
[encoder encodeObject:backgroundColor forKey:@"backgroundColor"];
[encoder encodeObject:tintColor forKey:@"tintColor"];
[encoder encodeObject:[NSNumber numberWithInt:bodyTextAlignment] forKey:@"bodyTextAlignment"];
}
Soluzione
È stato serializzato utilizzando un singolo oggetto radice, ma si tenta di deserializzare usando un tasto che non esiste a quel livello.
vuoi unarchiveObjectWithData:
, come in:
NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
PSYDefaults *decodedDefaults = [NSKeyedUnarchiver unarchiveObjectWithData:codedData];
.
Nota che dovrai anche implementare initWithCoder:
come controparte a encodeWithCoder:
. Anche se sembra che tu voglia avere un singleton qui, NSscoDing richiede di creare un nuovo oggetto qui a causa di [NSKeyedArchiver archivedDataWithRootObject:sharedInstance]
.
Se si desidera EN / decodificare i campi senza creare una nuova istanza di PSYDefaults
, è necessario utilizzare - [NSKEYEDArchiver INITFORRAWRINGWITHUMUTOBATATE:] e passare quell'archivio a un metodo simile a Il tuo encodeWithCoder:
(ma dovresti dargli un nome diverso allora). Quindi scriveresti una contropartita che legge i campi indietro tramite un NSKeyedUnarchiver
in cui si utilizza decodeObjectForKey:
e Amici per ogni campo.
Potresti anche voler leggere il Archivi e Guida alla programmazione serializzations .
Altri suggerimenti
Prova a salvare il tuo oggetto usando:
[NSKeyedArchiver archiveRootObject:object toFile:filePath];
.
e caricalo usando:
[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
.
I Uso i metodi sopra per salvare NSDITICARIO con oggetto personalizzato in un file.
E inoltre dovresti avere la funzione InitWithCoder: (NSCoder *) decodificatore nel tuo oggetto. Che decodifica i dati usando
[decoder decodeObjectFoyKey:yourKey];
. Ho avuto un altro problema con il metodo NSCoder's
decodeObjectForKey
durante l'utilizzo di FXForm
: si è schiantato senza alcuna spiegazione.
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
self.someObject = [decoder decodeObjectForKey:@"someObject"];
}
return self;
}
.
La ragione era in problemi di memoria.Comunemente, sembra che quando non vi è alcuna spiegazione di un bug nei registri, significa che è un problema di memoria.Ho dimenticato di utilizzare il corretto attributo della proprietà - copia.Ho usato invece Assegna.Questo è il codice corretto:
@interface MyClass : : NSObject <FXForm, NSCoding>
@property (nonatomic, copy) SomeClass *someObject;
@end
.
Solo nel caso qualcuno incontra anche questo problema.