NSKeyedArchiver: distinguishing between different instances of the same class

1.9k views Asked by At

I'm implementing support for Lion's "Resume" feature in my OS X app.

I have a custom subclass of NSViewController in which I implemented the method encodeRestorableStateWithCoder: as:

@implementation MyClass (Restoration)
    -(void)encodeRestorableStateWithCoder:(NSCoder*)coder {
       [coder encodeObject:_dataMember forKey:@"object_key"]; // I get the warning below when this line is executed for the second time
    }
    - (void)restoreStateWithCoder:(NSCoder *)coder {
       _dataMember = [coder decodeObjectForKey:@"object_key"];
    }
@end

However, since I have multiple instances of MyClass, different values are saved into the same key ("object_key") and I get the following warning from Cocoa:

NSKeyedArchiver warning: replacing existing value for key 'object_key'; probable duplication of encoding keys in class hierarchy

What is the best practice to overcome this problem?

Edit: I found here that each instance automatically has its own namespace to avoid collisions, so the problem might be in the way I'm manually calling encodeRestorableStateWithCoder to different instances with the same NSCoder object without telling it that these are different instances. However, I still can't figure out how to do that properly.

Thanks in advance!

1

There are 1 answers

3
Yoav On BEST ANSWER

To overcome this problem, it is possible to create a new NSMutableData where each of which is written by a separate (new) NSKeyArchiver, and store them all in an array which is stored in the original NSCoder object.

Here is an example for encoding the restorable state of subitems. The decoding part can be straight-forward given this code.

- (void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
    [super encodeRestorableStateWithCoder:coder];

    // Encode subitems states:
    NSArray* subitems = self.items;
    NSMutableArray* states = [NSMutableArray arrayWithCapacity: subitems.count];
    for (SubItemClass* item in subitems)
    {
        NSMutableData* state = [NSMutableData data];
        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:state];
        [item encodeRestorableStateWithCoder:archiver];
        [archiver finishEncoding];
        [states addObject:state];
    }
    [coder encodeObject:states forKey:@"subitems"];
}