iOS 4 iPhone アプリケーションで CoreData (ストアとして SQLite を使用) を使用して、最初に xml ファイルから取得したデータを保存しています。私のデータ モデルには 15 を超えるエンティティが含まれており、データ モデルのオブジェクト グラフを表すためにすべての NSManagedObject をメモリ内に作成する CoreData を見たので、メモリの消費が心配です。SAX libxml2 ベースのパーサーを使用して xml ファイルを解析し、エンティティの各「集合セット」をチャンクごとに一緒に格納しようとしますが、この集合が挿入され、マネージド コンテキストが保存された後に、各マネージド オブジェクトを解放したいと思います。次の凝集のためにメモリを節約します。(データモデルで設計されているように)リレーションシップによって他のオブジェクトに関連付けられている間に、各オブジェクトが受け取った複数の保持を相殺するために、refreshObject: mergeChanges: を使用する必要があることがわかりました。コンテキストを保存した後にそれを行いますが、次に、何も返さない前に挿入したものを取得しようとして、ストアを再度検索しようとします。何か不足していますか?
3 に答える
インポートするだけの場合 (たとえば、挿入されたオブジェクトをユーザーに表示するために保持する必要がないなど)、[moc reset]
保存後に簡単に使用できます。したがって、アルゴリズムは次のようになります。
NSManagedObjectContext* moc = ...;
while ([xmlData hasMoreObjects]) {
// Create e.g. 500 objects and insert them into the managed object context
NSError* error = nil;
if (![moc save:&error]) {
// handle the error
}
[moc reset]; // Here the inserted objects get released in the core data stack
}
管理オブジェクト コンテキストのリセットは、すべてのオブジェクトを更新する場合と同じです (以前に行ったように)。[[NSManagedObject alloc] initWithEntity:insertIntoManagedObjectContext:]
また、 の便利なメソッドの代わりに を使用することを検討するNSEntityDescription
必要があります。これは、不要になった直後に解放でき、自動解放プールがクリアされるまでメモリにとどまらないためです。
コア データ プログラミング ガイドを参照してください。これには、効率的なデータのインポートを中心としたセクション全体と、コア データを使用したメモリ管理に関するセクションが含まれています。
コンテキストがオブジェクトのライフサイクルを制御してグラフの整合性を維持しているため、管理対象オブジェクトのメモリを直接/手動で管理することはできません。
個別のチャンクでインポートを処理できる場合は、各チャンクの後にコンテキストを保存し、続いて次のようにします。
[context refreshObject:theObject mergeChanges:NO]
...これにより、新しく保存されたオブジェクトがフォールトに変換されるため、メモリをほとんど消費しません。
関係を設定するのに必要なのはフォールトのみであるため、前のチャンクで処理されたオブジェクトは、現在のチャンクの関係で設定するために引き続き使用できます。
可能な限り、1 つのパスでオブジェクトを作成し、それらを保存し、それらをフォールトに変換してから、次のパスで関係を設定します。必要な関係がある場合、これは必ずしも実用的ではありません。
まだ行っていない場合は、Core Data Programming Guide: Efficiently Importing Dataを確認することをお勧めします。
変更ごとにこれを行う必要があると思います
NSManagedObjectContext *moc;
NSError *error;
[moc save:&error];
それ以外の場合は破棄されます