NSKeyedUnarchiver unarchiveObjectWithFile: возвращает ноль в init: метод - PullRequest
9 голосов
/ 29 августа 2009

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

Меня очень смущает поведение NSKeyedUnarchiver unarchiveObjectWithFile :. В документации сказано, что он вернет ноль, если файл не существует. С одним из моих объектов происходит следующее:

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 :. Что я делаю неправильно, мешая мне вернуть объект Game из архива?

Ответы [ 2 ]

8 голосов
/ 09 декабря 2011

Я столкнулся с той же проблемой в 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!!!

Кажется, это ошибка в touch-какао.

Edit:

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

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

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

NSKeyedUnarchiver *coder = [[self alloc] initForReadingWithData:arg2];
id object = [coder decodeObjectForKey:@"root"];
2 голосов
/ 13 декабря 2010
  1. Вы всегда должны -retain разархивированный объект: Game *g2 = [[NSKeyedUnarchiver unarchiveObjectWithFile:archivePath] retain];

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...