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"];
}
.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top