web-dev-qa-db-ja.com

NSArrayをコアデータのサンプルコードに格納しますか?

私はしばらくの間、コアデータにNSArrayを格納する方法に関するサンプルコードを探していましたが、うまくいきませんでした。誰かが私にいくつかのチュートリアルや例を示してもいいですか、それともこの質問への回答として簡単なサンプルを書いてもいいですか?私は this を読みましたが、NSArrayである変換可能な属性を実装する方法の例は示していません。前もって感謝します!

29
Stunner

本当に必要な場合は、データとしてエンコードしてください。私は単にreceiveという新しいフィールドをNSData(バイナリデータ)として作成しました。

次に、NSManagedObject実装で:

-(void)setReceiveList:(NSArray*)list{
     self.receive = [NSKeyedArchiver archivedDataWithRootObject:list];
}

-(NSArray*)getReceiveList{
    return [NSKeyedUnarchiver unarchiveObjectWithData:self.receive];
}
37
Resh32

変換可能な属性は、コアデータ(NSArrayなど)でサポートされていないオブジェクト値を保持するための正しい方法です。 From コアデータプログラミングガイド:非標準の永続属性

変換可能な属性の背後にある考え方は、属性に非標準型としてアクセスすることですが、裏では、Core DataはNSValueTransformerのインスタンスを使用して、属性をNSDataのインスタンスとの間で変換します。次に、コアデータはデータインスタンスを永続ストアに格納します。

変換可能な属性は、NSValueTransformerを使用して、サポートされていないオブジェクトを永続ストアに格納します。これにより、Core DataはNSDataとして表すことができるほぼすべてのものを保存できます。これは非常に便利です。残念ながら、変換可能な属性を述語で照合したり、NSSQLiteStoreTypeを使用した結果の並べ替えに使用したりすることはできません。つまり、変換可能な属性は、オブジェクトの検出ではなく、ストレージにのみ役立ちます。

デフォルトのトランスフォーマーでは、NSCoding(またはNSSecureCoding)をサポートするすべてのオブジェクトを変換可能な属性として保存できます。これには、NSArrayUIColorUIImageNSURLCLLocationなどが含まれます。これは、ストアをクエリするときにパフォーマンスに大きな影響を与える可能性があるため、任意に大きくなる可能性のあるデータに使用することはお勧めしません。たとえば、イメージは、変換可能な属性にはあまり適していません。イメージは、ストアを断片化する大きなバイトのバッグです。その場合は、Core Dataの外部レコードストレージ機能を使用するか、データをファイルとして個別に保存し、ファイルへのURLをCore Dataに保存することをお勧めします。 UIImageをコアデータに格納する必要がある場合は、関連するトレードオフを必ず知っておいてください。

変換可能な属性の作成は簡単です。

•Xcode Core Data Model Editorで、変更するモデル属性を選択します。右側のインスペクタで、属性タイプを「変換可能」に設定します。 「名前」フィールドを空白のままにして、デフォルトのトランスフォーマーを使用できます。カスタムトランスフォーマーを使用している場合は、ここにクラス名を入力し、コードのどこかに_+[NSValueTransformer setValueTransformer:forName:]_を使用してクラスを登録します。

Core Data Model Editor Transformable Attribute

NSManagedObjectサブクラスヘッダーで、正しいタイプの変換可能な属性を説明するプロパティを宣言します。この例では、NSArrayを使用しています。

@property (nonatomic, retain) NSArray *transformedArray;

NSManagedObjectサブクラス実装ファイルでは、プロパティを動的にする必要があります。

_@dynamic transformedArray;_

これで完了です。 NSArray値オブジェクトが_setTransformedArray:_に渡されると、その配列はオブジェクトによって保持されます。コンテキストが保存されると、Core Dataはモデルに記述されているNSArrayを使用してNSDataNSValueTransformerに変換します。 NSDataバイトは永続ストアに保存されます。

29
quellish

NSArrayをCore Dataにネイティブに保存することはありません。格納された値を変換する必要がありますwithin配列をCore Dataが使用できるものに変換し、データをストアに保存して、必要に応じてNSArrayにプッシュおよびプルできるようにします。 。

26
Philip Regan

フィリップの答えは正しいです。 Core Dataには配列を格納しません。コアデータの目的に完全に反します。ほとんどの場合、配列の情報は必要ありませんが、配列の情報は必要なく、Core Dataによって動的にロードできます。コレクションの場合、プロパティの配列またはNSSet(基本的には単なる配列です)でフェッチされた結果の配列を繰り返し処理しても、違いはありません。

ここにフィリップが言ったことの説明があります。配列を直接格納することはできませんが、配列からプロパティリストを作成できます。すべてのNS Arraytypesには、素敵でクリーンな文字列とコアデータラブ文字列を提供するメソッドがあります。文字列として格納されたプロパティリストのクールな点は、それらが元の状態になることです。 NSStringのメソッドです。Tataaa...

もちろん価格があります。プロパティリストとしての配列は巨大になる可能性があり、RAMが制限されているiOSデバイスではうまく機能しません。配列をコアデータに保存しようとすると、特に大きなデータのエンティティデザインが不適切であることを示します。A速度の理由から、小さな配列で問題ありません。

スペースをあまり消費しないもう1つの方法は、バイナリプロパティリストを使用することです。これらは、Core Dataまたはファイルシステムに直接保存すると、Zipサイズに近くなります。欠点は、XMLファイルやJSONファイルのように単純に開いて読み取ることができないことです。開発には人間が読めるものを好み、バイナリバージョンをリリースします。プリプロセッサのDEBUG値に関連付けられた定数がそれを処理するので、コードを変更する必要はありません。

8
Helge Becker

Core Dataは、NSManagedObjectまたは同じのサブクラスのインスタンスを保存します。 NSManagedObject自体は、非常に辞書に似ています。オブジェクト間の多対多の関係は、セットとして表されます。コアデータには、配列に対応する順序付きリストがありません。代わりに、Core Dataストアからオブジェクトを取得するときは、フェッチ要求を使用します。そのフェッチ要求は、オブジェクトのソートに使用される1つ以上のソート記述子を指定でき、フェッチ要求によって返されたオブジェクトは配列に格納されます。

オブジェクトの順序を維持することが重要な場合は、オブジェクトをフェッチするときにオブジェクトをソートするために使用できる属性をエンティティに含める必要があります。

1
Caleb