开发者

When decoding an object from NSCoder, what's the best way to abort?

I'm decoding a custom object from a cached serialization. I've versioned++ the object since it was encoded, and if the serialized version is an old version I want to just throw it away. I was under the impression that I could just return nil from my initWithCoder: method and all would be well. That's throwing an error though.

EDIT - Per NSObject's +version: documentation "The version number applies to NSArchiver/NSUnarchiver, but not to NSKeyedArchiver/NSKeyedUnarchiver. A keyed archiver does not encode class version numbers.". I'm using a keyed archiver so that approach won't help.

I am using my own embedded version number, not the NSObject version + NSCoder's versionForClassName:. Is that the way to go about this? Will NSCoder automatically abort attempting to decode if the Class versions don't match, or do I need to do this check manually.

I'm currently doing this:

- (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;
    }

    ...
}

and I'm getting this error when it tries to decode old versions

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

This all seems odd because initializers can fail for any number of reasons, and the pattern is to return nil in that case, so should this really crash a decoder?

EDIT - Per Apple's documentation it sounds like I'm approaching this the right way. There does not appear to be, however, a mechanism for completely aborting decoding if an object is old and out of date. I don't have or want an upgrade path from the old object, so what do I do?


instead of setting self to nil, set all of the individual properties that you decode to nil, then return self. So, write this:

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

This will essentially return an object of the right type and all, but all properties will be nil.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜