1

これに完全に対処していない先行技術: コアデータ移行エラーメッセージ「'モデルに構成'XYZ'が含まれていません。」

これを特定の問題に絞り込みました。ただし、セットアップには1分かかります。我慢してください。

問題の要点は、persistentStoreCoordinatorが(明らかに)管理対象オブジェクトが別のファイルに保存されているときに別のサブエンティティとしてマークされているオブジェクトグラフの部分を保持できないことです。ここに行く...

1)2つのxcdatamodelファイルがあり、それぞれに1つのエンティティが含まれています。実行時に、管理対象オブジェクトモデルが構築されるときに、setSubentities:を使用して、あるエンティティを別のエンティティのサブエンティティとして手動で定義します。これは、エディターで複数のファイルにまたがるサブエンティティーの定義がまだサポートされていないためです。次に、modelByMergingModelsを使用して完全なモデルを返します。

//Works! 
[mainEntity setSubentities:canvasEntities];
NSLog(@"confirm %@ is super for %@", [[[canvasEntities lastObject] superentity] name], [[canvasEntities lastObject] name]);
//Output: "confirm Note is super for Browser"

2)エンティティごとに異なるストアを設定するようにpersistentStoreCoordinatorメソッドを変更しました。技術的には、構成を使用し、各エンティティには1つだけの構成が定義されています。

//Also works!
for ( NSString *configName in [[HACanvasPluginManager shared].registeredCanvasTypes valueForKey:@"viewControllerClassName"] ) {
storeUrl = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:[configName stringByAppendingPathExtension:@"sqlite"]]];
//NSLog(@"entities for configuration '%@': %@", configName, [[[self managedObjectModel] entitiesForConfiguration:configName] valueForKey:@"name"]);
//Output: "entities for configuration 'HATextCanvasController': (Note)"
//Output: "entities for configuration 'HAWebCanvasController': (Browser)"
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:configName URL:storeUrl options:options error:&error])
//etc

3)親エンティティにfetchRequestを設定し、setIncludesSubentities:とsetAffectedStores:を使用して、1)と2)の両方がカバーされていることを確認します。いずれかのエンティティのオブジェクトを挿入すると、両方がコンテキストに追加され、両方ともfetchedResultsControllerによってフェッチされ、期待どおりにtableViewに表示されます。

// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesSubentities:YES]; //NECESSARY to fetch all canvas types
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:20]; // Set the batch size to a suitable number.
[fetchRequest setAffectedStores:[[managedObjectContext persistentStoreCoordinator] persistentStores]];
[fetchRequest setReturnsObjectsAsFaults:NO];

ここで誤動作が始まります。アプリを閉じて再起動すると、親エンティティのみが取得されます。

setEntity:を使用してリクエストのエンティティを「Note」のエンティティに変更すると、すべてのノートがフェッチされます。'Browser'のエンティティに変更すると、すべてのブラウザがフェッチされます。オブジェクトが最初にコンテキストに挿入される実行中に、オブジェクトがリストに表示されることを繰り返します。フェッチ要求が階層をトラバースできないのは、保存して再起動した後だけです。

したがって、問題は継承のストレージであると結論付けることしかできません。理由を要約しましょう:

    -両方のエンティティを作成し、コンテキストに挿入して表示できるため、モデルは機能しています
    -両方のエンティティを1回のリクエストでフェッチできるため、継承が機能しています
    -ファイルが個別に保存され、オブジェクトが適切なストアに格納されていることを確認できるため、保存が機能しています
    -リクエストにいずれかのエンティティが設定された状態でアプリを起動すると機能するため、ストアからの取得が機能します
    -これは、リクエストでさまざまなストアをトラバースすることも機能していることを意味します
    -複数ではなく単一のストアを使用することで、問題が完全に解消されるため、作成、保存、フェッチ、表示などが正しく機能します。

これにより、(私の考えでは)1つの原因のみが残ります。setSubentitiesで設定している継承:は、セッション中に作成されたオブジェクトに対してのみ有効です。

オブジェクト/エンティティが継承情報を取り除いて保存されているか、プログラムで定義されたエンティティの継承が新しいインスタンスにのみ適用されるか、またはその両方です。これらのいずれも受け入れられません。それはバグであるか、私は道を外れています。

私は2日間、あらゆる方法でこれに取り組んできました。どんな洞察も大歓迎です。現在の回避策(単一のストアを使用するだけ)は完全に機能しますが、アプリからモデルの1つを削除した場合など、将来にわたって利用できるわけではありません。また、理由がわからないため、頭がおかしくなります。 (setSubentities :)のコア定義で機能しない場合は、複数のストアにまたがって保存し、影響を受けるストアをフェッチ要求に設定するためのこのすべてのインフラストラクチャがあります。

4

2 に答える 2

4

答えは残念ながら簡単です。物理的に異なるファイルやモデルにまたがるサブエンティティはサポートされていません。基礎となるデータ構造では、Core Data はすべてのサブエンティティを取得し、それらを 1 つのテーブルにフラット化します。したがって、それぞれ 4 つの属性を持つ Parent、ChildA、ChildB、および ChildC がある場合、16 列の単一のテーブルになります。

これが、試みている方法でサブエンティティがサポートされていない理由です。各モデルはそれ自体がサイロであり、せいぜい他のモデル内のオブジェクトへの弱い参照を持つことができます。

アップデート

上で説明したように、「設計上サポートされていない」問題です。あなたがしようとしていることは、基礎となるデータ構造に永続化されているため、サポートされていません。サブエンティティの作成は、データ モデルを平坦化するため、最初から多くのことを行うべきではありません。

エンティティの継承は、オブジェクトの継承と同じではありません。オブジェクトは、好きな形や形で継承できます。エンティティの継承は非常にまれであり、その背後には非常に正当な理由があります。

親子関係の問題を解決することは、エンティティの継承を使用する数少ない理由の 1 つです。

列の重複を避けようとするのは正当な理由ではありません

モデル間で親子関係を作成することはできません (また、モデルが の 1 つのインスタンスにマージされている場合でも複数のモデルが存在しますNSManagedObjectModel) ため、解決できないモデル間でエンティティの継承を行う理由にはなりません。同様のソリューションを介して。

于 2010-05-03T22:27:43.637 に答える
0

@SG

あなたが尋ねる:

複数のモデルを読み取り、複数の永続ストアに保存するためのフックがすべてあるのはなぜですか...

xcdatamodel のさまざまな部分で作業したいため、複数のモデルを用意して、それらをさまざまな永続ストアに保存できます。たとえば、EntityA の属性を編集して EntityB との関係に影響を与えながら、EntityB の膨大な量の managedObjects を並べ替えます。

新しいオブジェクトを読み込んでいる間に、別のスレッドでより良い I/O ストリーミングを実行することもできます。この作業が完了したら、それらをモデルの既存のデータと「マージ」できます。

于 2011-07-14T15:31:18.607 に答える