2016-11-18 4 views
0

私はNSCodingに準拠した(そしてディスクにアーカイブされている)オブジェクトを持っています。このオブジェクトの1つのプロパティ(myMetrics)はNSDictionaryです。新しいバージョンのソフトウェアでは、この辞書にキーを追加する必要がありますが、アプリケーションの残りの部分が主要なオブジェクトを必須のキーとして使用する前に、それを行う必要があります。NSDictionaryからObjectへの移行に最適な方法

-(id)initWithCoder:(NSCoder *)coder 
{ 
    if (self = [super init]) 
    { 
     self.myMetrics = [coder decodeObjectForKey:@"myMetrics"]; 
     ... other properties go here .... 
    } 

    .... add the new key to myMetrics with default value if it is missing in myMetrics ... 

    return (self); 
} 

私が本当にやりたいことはそれ自身のクラスに辞書からmyMetricsを変換です:

私の考えはような何かをすることでした。私はすでに存在するアーカイブされたオブジェクトに対してこれをどのように処理するのか分かりません。私の考えは:

  1. newMetricsという名前のクラスの新しいプロパティを追加しました。
  2. myWebCoderでmyMetricsプロパティが見つかった場合、そのデータをnewMetricsプロパティに移動します。
  3. in encodeWithCoderではnewMetricsのみを処理し、古い辞書は再エンコードしません。

この方法では、ソフトウェアはNewMetricsオブジェクトを使用しますが、initWithCoderは古いスタイルのmyMetricsを処理できます。

同じプロパティ名を維持しながらこれを行う良い方法はありますか?

@property (atomic, retain) NSDictionary* myMetrics; // dictionary of parameters 

becomes 

@property (atomic, retain) NewMetrics* myMetrics; // parameters 

rather than 

@property (atomic, retain) NewMetrics* newMetrics; // parameters 

良い方法はありますか?

+0

あなたは新しいクラス 'NewMetrics'をいくつかの場所で呼び出し、' MyMetrics'を他の場所で呼び出します。あなたはあなたの質問を編集して、どちらか一方を使うことができますか? –

+0

申し訳ありません - 修正されました。 – Trygve

答えて

1

はい、既存のアーカイブ済みオブジェクトを処理しながら、プロパティの名前を変更せずに辞書からmyMetricsを独自のクラスに変換できます。新しいプロパティの宣言は次のようになります。

@property (atomic, retain) NewMetrics* myMetrics; // parameters 

initWithCoder:機能のようなものになります:あなたは、例えば、新しいキーの下myMetricsプロパティをエンコードを開始しなければならない

-(id)initWithCoder:(NSCoder *)coder 
{ 
    if (self = [super init]) 
    { 
     // decode saved NewMetrics object 
     self.myMetrics = [coder decodeObjectForKey:@"newMyMetrics"]; 
     if (!self.myMetrics) { 
      // fall back to legacy saved metrics NSDictionary 
      NSDictionary *legacyMetrics = [coder decodeObjectForKey:@"myMetrics"]; 
      if (legacyMetrics) { 
       self.myMetrics = [[NewMetrics alloc] initWithDictionary:legacyMetrics]; 
      } else { 
       // handle having no saved metrics 
      } 
     } 

     ... other properties go here .... 
    } 

    return self; 
} 

古いスタイルのメトリック辞書を新しいNewMetricsクラスのインスタンスに変換する方法を提供します。たとえば、次のようにします。 initWithDictionary:である。

+0

id tempMetrics = [コーダーdecodeObjectForKey:@ "myMetrics"];次に、if([tempMetrics isKindOfClass:[NSDictionary class]])をテストして、新しいキーの下でそれをコーディングする必要はありませんか? – Trygve

+0

あなたはそうすることができますが、古いバージョンのアプリケーションが新しいバージョンで保存されたアーカイブをデコードしようとすると、クラッシュする可能性があります。同じキーが2つの異なるタイプのデータを参照することは、私にとって間違っていると感じます。新しい鍵を使いたくない理由がありますか? –

+0

ほとんどの場合、暗号化キーはプロパティキーと一致します。 v1アプリケーションでv2ドキュメントを開くことができない(そしてNSDocumentのサブクラスでこれをチェックする)理由があります。提案に感謝....実際に役立つ。 – Trygve

関連する問題