2009-08-29 18 views
7

Aggiornamento: Questo funziona se chiamo archiveRootObject: from applicationDidFinishLaunching :. Se lo chiamo dal metodo init: di una classe singleton, restituisce nil.NSKeyedUnarchiver unarchiveObjectWithFile: restituisce nil in init: metodo

Sono molto confuso dal comportamento di NSKeyedUnarchiver unarchiveObjectWithFile :. The documentation dice che restituirà nil se il file non esiste. Con uno dei miei oggetti, accade quanto segue:

Game *g1 = [Game getGame]; 
NSString *archivePath = [Game getArchivePath]; 
bool success = [NSKeyedArchiver archiveRootObject:g1 toFile:archivePath]; 
Game *g2 = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath]; 

// success is true, g2 is nil 

Ho verificato che il file in realtà esiste ed è sempre scritto per l'archiveRootObject: metodo. Cosa sto facendo male mi impedisce di recuperare un oggetto di gioco dall'archivio?

+0

Dubito che questo risolva la tua domanda, ma in Objective-C il termine corretto è 'BOOL' invece di' bool'. – jbrennan

+0

Grazie per il suggerimento. Questo è il mio primo progetto Objective-C. Ho aggiornato tutti i miei bool in quelli di BOOL. – brantonb

+0

Impostare un punto di interruzione su objc_exception_throw e verificare se viene sollevata un'eccezione. – peterb

risposta

2
  1. Si deve sempre -retain un oggetto non archiviata: Game *g2 = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];

  2. Il vostro g2 conformarsi alle NSCoding? Assicurati che lo faccia, se non dichiara <NSCoding> nell'intestazione g2. Nel file di implementazione definire i metodi -(id)initWithCoder:(NSCoder *)coder e -(void)encodeWithCoder:(NSCoder *)coder

  3. Se stai lottando per arrivare a questo lavoro considerare l'archiviazione e unarchiving uno standard NSObject, come un NSString o qualcosa del genere. Probabilmente non è necessario archiviare un intero oggetto personalizzato, magari solo un numero di tempo rimanente, una posizione di gioco o una posizione o un punteggio. In altre parole, archivia e disarchivi il minimo indispensabile di cui hai bisogno.

7

ho incontrare lo stesso problema in Xcode 4.1 con il supporto ARC:

BOOL isFileExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath]; 
NSAssert(isFileExist, @"filePath does not exist"); 
NSKeyedUnarchiver* coder = 
    [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; // nil 
NSData* data = [[NSFileManager defaultManager] contentsAtPath:filePath]; 
coder = [NSKeyedUnarchiver unarchiveObjectWithData:data]; // nil 
coder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; // OK!!! 

Sembra essere un bug nel cacao-touch.

Edit:

Esso è destinato a comportarsi in questo modo e non è un bug. Ma sono d'accordo sul fatto che la denominazione porta facilmente agli errori.

[[NSKeyedUnarchiver alloc] initForReadingWithData:] restituisce un'istanza NSKeyedUnarchiver.

[NSKeyedUnarchiver unarchiveObjectWithData:] restituisce l'oggetto radice. È un metodo conveniente per:

NSKeyedUnarchiver *coder = [[self alloc] initForReadingWithData:arg2]; 
id object = [coder decodeObjectForKey:@"root"]; 
+1

Lo stesso problema anche su Mac. Grazie mille! –

Problemi correlati