私はiOS5アプリケーションでインポートしようとしているレールアプリからのプレイスのリストを持っています。各プレイスには、プレイス自体の親があります。私は辞書コアデータ:エントリを検索または挿入/重複してツリー構造をインポート
- (void)initWithDictionary:(NSDictionary *)dictionary {
self.placeId = [dictionary valueForKey:@"id"];
id parent = [dictionary objectForKey:@"parent"];
if (parent && parent != [NSNull null]) {
NSDictionary *parentDictionary = parent;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"placeId = %@", [parentDictionary objectForKey:@"id"]];
NSArray *matching = fetchedWithPredicate(@"Place", self.managedObjectContext, predicate, nil);
if ([matching count] > 0) {
self.parent = [matching objectAtIndex:0];
} else {
self.parent = [NSEntityDescription insertNewObjectForEntityForName:@"Place" inManagedObjectContext:self.managedObjectContext];
[self.parent initWithDictionary:parentDictionary];
}
}
}
fetchedWithPredicateを使用してコアデータとそのJSONデータをインポートしようとしている
は私もPlace.mで検証メソッドを持っているように
NSArray* fetchedWithPredicate(NSString *entityName, NSManagedObjectContext *context, NSPredicate *predicate, NSError **error) {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setIncludesPendingChanges:YES];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
[request setEntity:entity];
[request setPredicate:predicate];
NSArray *result = [context executeFetchRequest:request error:error];
return result;
}
として定義されたメソッドであります同じplaceId(placeIdはサーバー側のID)で配置するように作成しないようにします。
- (BOOL)validatePlaceId:(id *)value error:(NSError **)error {
if (*value == nil)
return YES;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"placeId = %@ AND (NOT self IN %@)", *value, [NSArray arrayWithObject:self]];
NSArray *matching = fetchedWithPredicate(@"Place", self.managedObjectContext, predicate, error);
if ([matching count] > 0) {
return NO;
}
else {
return YES;
}
}
データをインポートするには、サーバーからすべての場所を取得し、JSON形式で戻します。 各プレイスには、独自の情報と、親に関する情報を持つ子ノードがあります。つまり、複数の子の各親が複数回表示されます。私は未保存の変更を含むフェッチし、大丈夫だろう、「検索または作成」の一種を行い、上記のコードを考え
{ "id": 73,
"name": "Some place",
"parent": { "id": 2,
"name": "Parent's name"}
}
ように見えます。 しかし、それはまだいくつかの場所の複数のエントリを作成しようとします(そして、そこにバリデーションがあるので失敗します)。深く見ると、実際には同じ場所ID(異なるポインタ)の異なるコアデータオブジェクトが挿入されますが、理由はわかりません。
おかげ
私は「setIncludesPendingChanges:YES」を有すると考え、私のフェッチにするには、オブジェクトを取得するのに十分でしたコンテキストを保存していないのに現在のコンテキスト。なぜこれが間違っているのか知っていますか? その答えがない限り、別の辞書の提案は私がやることです。 – Nycen
私はpendingChanges(ここで推測)は、メインスレッド/実行ループ上にいる場合は定期的に呼び出されるはずですが、各ループに対して通常の '[moc processPendingChanges]'コールを追加するかどうかだけを知るかもしれないと思います。 –