ベストプラクティス?-コアデータエンティティ属性としての配列/辞書[終了]


176

Core Dataは初めてです。コレクションタイプは属性タイプとして使用できないことに気づきました。配列/辞書タイプのデータを属性として保存する最も効率的な方法は何かを知りたいと思います(たとえば、番地、都市などの住所を構成する要素は、個別のエンティティを必要とせず、個別の属性/フィールドよりも辞書/配列としてより便利に保存されます)。ありがとうございました。


6
...アドレスの文字列フィールドを持つエンティティは、おそらくあなたがあなたの鍵を覚えている辞書よりも使いやすくなって作る
ダニエル

回答:


247

Core Dataには「ネイティブ」の配列または辞書タイプはありません。NSArrayまたはをNSDictionary変換可能な属性として保存できます。これはを使用しNSCodingて、配列またはディクショナリをNSData属性にシリアル化します(アクセス時に適切に逆シリアル化します)。このアプローチの利点は、簡単であることです。欠点は、配列または辞書(データストアにBLOBとして格納されている)にクエリを実行できないことと、コレクションが大きい場合、大量のデータをデータストアとの間で移動する必要がある場合があります(データストアの場合) SQLiteデータストア)を使用して、コレクションのごく一部を読み取るか変更します。

代わりの方法は、Core Dataの多対多の関係を使用して、配列または辞書コレクションのセマンティクスをモデル化することです。配列の方が簡単なので、それから始めましょう。コアデータと多対多の関係は実際にセットをモデル化しているため、配列のような機能が必要な場合は、セットを並べ替える(フェッチしたプロパティを使用すると、これを行うのに便利な方法です)か、エンティティに追加のインデックス属性を追加する必要があります配列項目を格納し、インデックスを自分で管理します。同種の配列(すべてのエントリが同じ型)を格納している場合、配列エンティティのエンティティの説明を簡単にモデル化できます。そうでない場合は、変換可能な属性を使用してアイテムデータを格納するか、アイテムエンティティのファミリを作成するかを決定する必要があります。

辞書のモデリングでは、キーと値を格納するエンティティのセットとの多対多の関係が必要になる可能性があります。キーと値はどちらも、上記の配列のアイテムエンティティに類似しています。したがって、それらはネイティブタイプ(事前に知っている場合)、変換可能な属性、またはタイプ固有のエンティティのファミリーからのインスタンスへの関係のいずれかになります。

このすべてが少し困難に聞こえる場合は、そうです。Core Dataのようなスキーマ依存のフレームワークに任意のデータを靴べらするのは難しいです。

住所などの構造化データの場合、エンティティを明示的にモデル化することに時間を費やす方が簡単です(例:住所の各部分の属性)。ディクショナリをモデル化するためのすべての追加コードを回避することに加えて、これにより、UIがより簡単になり(バインディングは「機能するだけ」)、検証ロジックなどがCore Dataで処理できるため、より明確になります。

更新

OS X 10.7以降、Core Dataには、配列の代わりに使用できる順序付きセットタイプが含まれています。10.7以降をターゲットにできる場合、これは順序付けられた(配列のような)コレクションの最良のソリューションです。


出向-私がすでに考えたことを確認しましたが、変換可能な属性について知りませんでした。
jkp

3
@pixelfreak変形可能オブジェクトの使用は、コレクション内のアイテムをどのように使用する必要があるによって異なります。それらに対してクエリを実行する必要がある場合、またはそれらの一部またはすべてを遅延ロードできるようにしたい場合、変換可能な属性は機能しません。遅延読み込みをする必要がない場合、クエリを実行する必要がない場合、常にすべてのアイテムを必要とするか、何も必要ない場合、変換可能な属性が機能する可能性があります(実装は簡単です)。
Barry Wark、2011

3
Barryの発言については、コアデータプログラミングガイドの非標準の永続属性の章で詳しく説明しています。
Palimondo 2011

2
順序付きセットに関する注意事項:多サイドで数千を超えるオブジェクトとの多対多の関係には使用しないでください。その場合、保存に時間がかかりすぎてスレッドがブロックされる可能性があります。
Kirk van Gorkom

2
「新注文セット」がわかりません。それは属性ですか?属性タイプメニューに表示されないためです。
2014年

11

同様の問題がありました。私の場合、文字列の配列をマップしたいと思いました。私はバリーのアドバイスに従い、ついにそれを機能させました。これは、一部のコードの外観です(これにより、他の人がこの問題に遭遇した場合にうまく理解できるようになります)...

私のエンティティは次のようになります:

@interface AppointmentSearchResponse : NSManagedObject
@property (nonatomic, retain) NSSet *messages;
@end

オブジェクトモデルの管理コード(コアデータ)のコードは次のようになります。

NSEntityDescription *entityDescription = [[NSEntityDescription alloc] init];
[entityDescription setName:@"AppointmentSearchResponse"];
[entityDescription setManagedObjectClassName:@"AppointmentSearchResponse"];

NSMutableArray *appointmentSearchResponseProperties = [NSMutableArray array];
NSAttributeDescription *messageType = [[NSAttributeDescription alloc] init];    
[messageType setName:@"messages"];
[messageType setAttributeType:NSTransformableAttributeType];
[appointmentSearchResponseProperties addObject:messageType];

[entityDescription setProperties:appointmentSearchResponseProperties];

したがって、ここでの重要な項目は次のとおりです。

  • プロパティタイプにNSSetを使用しています
  • Core Data Managed Object Modelの属性タイプとしてNSTransformableAttributeTypeを使用しています。

では、このコードをinitメソッド内のAppointmentSearchResponse.m内に配置しますか?
Chicowitz、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.