Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSKeyedUnarchiver unarchiveObjectWithFile: returns nil in init: method

Update: This works if I call archiveRootObject: from applicationDidFinishLaunching:. If I call it from the init: method of a singleton class, it returns nil.

I'm very confused by the behavior of NSKeyedUnarchiver unarchiveObjectWithFile:. The documentation says that it will return nil if the file doesn't exist. With one of my objects, the following happens:

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

I've verified that the file actually does exist and is getting written to by the archiveRootObject: method. What am I doing wrong preventing me from getting a Game object back out of the archive?

like image 765
brantonb Avatar asked Aug 29 '09 18:08

brantonb


1 Answers

I've meet the same trouble in Xcode 4.1 with ARC support:

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!!!

It seems to be a bug in cocoa-touch.

Edit:

It is intended to behave like this and is not a bug. But I agree that the naming easily leads to mistakes.

[[NSKeyedUnarchiver alloc] initForReadingWithData:] returns a NSKeyedUnarchiver instance.

[NSKeyedUnarchiver unarchiveObjectWithData:] returns the root object. It is a conviencen method for:

NSKeyedUnarchiver *coder = [[self alloc] initForReadingWithData:arg2];
id object = [coder decodeObjectForKey:@"root"];
like image 60
poGUIst Avatar answered Dec 14 '22 22:12

poGUIst