2

OSXアプリにLionの「再開」機能のサポートを実装しています。

NSViewControllerのカスタムサブクラスがあり、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

ただし、MyClassのインスタンスが複数あるため、異なる値が同じキー( "object_key")に保存され、Cocoaから次の警告が表示されます。

NSKeyedArchiver警告:キー'object_key'の既存の値を置き換えます。クラス階層でのエンコーディングキーの重複の可能性

この問題を克服するためのベストプラクティスは何ですか?

編集:衝突を避けるために、各インスタンスには自動的に独自の名前空間があることがわかりまし。そのため、同じNSCoderオブジェクトを持つ別のインスタンスに対してencodeRestorableStateWithCoderを手動で呼び出しているときに、これらが異なるインスタンスであることを通知せずに問題が発生する可能性があります。しかし、それを正しく行う方法がまだわかりません。

前もって感謝します!

4

1 に答える 1

1

この問題を克服するために、それぞれが個別の(新しい)NSKeyArchiverによって書き込まれる新しいNSMutableDataを作成し、それらすべてを元のNSCoderオブジェクトに格納されている配列に格納することができます。

サブアイテムの復元可能な状態をエンコードする例を次に示します。このコードがあれば、デコード部分は簡単です。

- (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"];
}
于 2012-08-23T05:38:38.583 に答える