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

I am decoding a custom object from cached serialization. I was versioning a ++ object since it was encoded, and if the serialized version is an old version, I just want to throw it away. I got the impression that I could just return zero from my initWithCoder method: and everything will be fine. However, this is a mistake.

EDIT - for NSObject + version: documentation "The version number applies to NSArchiver / NSUnarchiver, but not to NSKeyedArchiver / NSKeyedUnarchiver. The archiver key does not encode class version numbers.". I use the archiver key, so the approach will not help.

I use my own built-in version number, not the NSObject + NSCoder versionForClassName: version. Is this the way to it? Will NSCoder automatically cancel the decoding attempt if the version of the classes do not match, or do I need to do this check manually.

I am 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 get this error when trying to decode old versions

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

All this seems strange, because initializers may fail for some reason, and the pattern should return zero in this case, so what should cause the decoder to crash?

EDIT - Per Apple Documentation , it looks like I'm approaching this correctly. However, there seems to be no mechanism to completely interrupt decoding if an object is out of date and out of date. I have no or no update path from the old object, so what should I do?

+4
source share
1 answer

instead of setting self to nil , set all the individual properties you are decoding 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 essentially returns an object of the correct type and all, but all properties will be nil .

+1
source

All Articles