Как лучше всего прервать декодирование объекта из NSCoder? - PullRequest
4 голосов
/ 09 июля 2011

Я декодирую пользовательский объект из кэшированной сериализации. Я версировал ++ объект, так как он был закодирован, и если сериализованная версия является старой версией, я хочу просто выбросить ее. У меня сложилось впечатление, что я могу просто вернуть nil из моего initWithCoder: method, и все будет хорошо. Это выдает ошибку, хотя.

EDIT - Для + версии NSObject: документация "Номер версии применяется к NSArchiver / NSUnarchiver, но не к NSKeyedArchiver / NSKeyedUnarchiver. Ключ-архиватор не кодирует номера версий классов.". Я использую архиватор с ключами, чтобы такой подход не помог.

Я использую свой собственный встроенный номер версии, а не версию NSObject + versionForClassName: версия NSCoder :. Это способ пойти по этому поводу? Будет ли NSCoder автоматически прервать попытку декодирования, если версии Class не совпадают, или мне нужно сделать эту проверку вручную.

Я сейчас занимаюсь этим:

- (id)initWithCoder:(NSCoder *)coder {
    if (![coder containsValueForKey:@"Class.User.version"]) {
        // Version information missing
        self = nil;
        return nil;
    }

    NSInteger modelVersion = [coder decodeIntForKey:@"Class.User.version"];
    if (modelVersion < USER_MODEL_VERSION) {
        // Old user model, discard
        self = nil;
        return nil;
    }

    ...
}

и я получаю эту ошибку при попытке декодировать старые версии

-[__NSPlaceholderDictionary initWithObjects:forKeys:]: number of objects (0) not equal to number of keys (46)'

Все это кажется странным, потому что инициализаторы могут потерпеть неудачу по любому количеству причин, и в этом случае шаблон должен возвращать ноль, так что должно ли это действительно привести к сбою декодера?

РЕДАКТИРОВАТЬ - По Документация Apple звучит так, будто я подхожу к этому правильному пути. Однако, по-видимому, не существует механизма полного прекращения декодирования, если объект устарел и устарел. У меня нет или я не хочу обновить путь со старого объекта, что мне делать?

1 Ответ

1 голос
/ 09 июля 2011

вместо установки self на nil, установите все индивидуальные свойства, которые вы декодируете, на nil, а затем верните self.Итак, напишите это:

if (modelVersion < USER_MODEL_VERSION) {
    // Old user model, discard
    object1 = nil;
    object2 = nil;
    ...
    object46 = nil;
}
return self;

Это по существу вернет объект правильного типа и все, но все свойства будут nil.

...