2009-08-29 3 views
7

Обновление: Это работает, если я вызываю archiveRootObject: from applicationDidFinishLaunching :. Если я вызываю его из метода init: метод singleton, он возвращает nil.NSKeyedUnarchiver unarchiveObjectWithFile: возвращает nil в init: метод

Я очень смущен поведением NSKeyedUnarchiver unarchiveObjectWithFile :. The documentation говорит, что он вернет нуль, если файл не существует. С одним из моих объектов, происходит следующее:

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 

Я проверил, что файл на самом деле существует и получение записывается в archiveRootObject: метод. Что я делаю неправильно, не позволяя мне вернуть объект игры из архива?

+0

Я сомневаюсь, что это решит ваш вопрос, но в Objective-C правильным термином является 'BOOL' вместо' bool'. – jbrennan

+0

Спасибо за подсказку. Это мой первый проект Objective-C. Я обновил все свои bool's до BOOL. – brantonb

+0

Установите точку останова в objc_exception_throw и проверьте, не возбуждено ли исключение. – peterb

ответ

2
  1. Вы должны всегда -retain разархивирована объект: Game *g2 = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];

  2. ли соответствует NSCoding ваш g2? Убедитесь, что он делает это, если он не объявляет <NSCoding> в заголовке g2. В файле реализации определяют методы -(id)initWithCoder:(NSCoder *)coder и -(void)encodeWithCoder:(NSCoder *)coder

  3. Если вы изо всех сил, чтобы получить эту работу рассмотреть архивирования и разархивирования стандартного NSObject, как NSString или некоторые такие. Вам, вероятно, не нужно архивировать целый пользовательский объект, может быть, просто оставшийся номер времени, местоположение игры или позицию или оценку. Другими словами, архивируйте и разархивируйте минимальный минимум, который вам нужен.

7

Я постигнет та же проблема в Xcode 4.1 с поддержкой 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!!! 

Это, кажется, ошибка в какао-контакт.

Edit:

Он предназначен для себя, как это и не ошибка. Но я согласен, что именование легко приводит к ошибкам.

[[NSKeyedUnarchiver alloc] initForReadingWithData:] возвращает NSKeyedUnarchiver экземпляр.

[NSKeyedUnarchiver unarchiveObjectWithData:] возвращает объект корня. Это метод conviencen для:

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

Такая же проблема на Mac. Спасибо! –

Смежные вопросы