0

データを Core Data にインポートするバックグラウンド スレッドで NSOperation を実行しています。これを行うには、最初にインポートのレコード (「インポート」) を作成してから、インポート レコードに関連するオブジェクトをインポートします。管理オブジェクト コンテキストを保存すると、次にインポートされたオブジェクトをインポート レコードにリンクしようとすると失敗します。

Illegal attempt to establish a relationship 'import' between objects in different contexts (source = <NSManagedObject: 0x1067bb730> (entity: Genre; id: 0x1053330c0 <x-coredata:///Genre/tC6A85CFE-3D0A-4E29-9186-4FD46104AEBC60> ; data: {
    import = nil;
    name = Polka;
}) , destination = <NSManagedObject: 0x106736170> (entity: Import; id: 0x103b571e0 <x-coredata://440D80CF-7C56-4B6F-9778-990032A76B8B/Import/p1> ; data: <fault>))

これが煮詰めたコードです。余分な保存を追加して効果を実証するために、コードを少し変更しました。通常、そこにある理由はありません。

NSError *writeError = nil;

TNAppDelegate *del = (TNAppDelegate *)[[NSApplication sharedApplication] delegate];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[del persistentStoreCoordinator]];
[moc setUndoManager:nil];

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
       selector:@selector(mergeChanges:)
           name:NSManagedObjectContextDidSaveNotification
         object:moc];

// create import instance
NSManagedObject *import = [NSEntityDescription insertNewObjectForEntityForName:@"Import" inManagedObjectContext:moc];
[import setValue:[NSDate date] forKey:@"start"];

[moc save:&writeError];
[moc reset];

NSString *newGenre = [songDictItem objectForKey:@"Genre"];
NSManagedObject *newGenreObject = [NSEntityDescription insertNewObjectForEntityForName:@"Genre" inManagedObjectContext:moc];
[newGenreObject setValue:newGenre forKey:@"name"];
[newGenreObject setValue:import forKey:@"import"]; // BOOM!

更新:リクエストにより、mergeChanges: のコードを提供しています。これは NSOperation にあります。メインの MOC に変更を保存する方法をいくつか試しましたが、すべて同じ方法で終了しまし

- (void)mergeChanges:(NSNotification*)notification
{
    TNAppDelegate *del = (TNAppDelegate *)[[NSApplication sharedApplication] delegate];
    if ([notification object] == [del managedObjectContext]) return;

    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(mergeChanges:) withObject:notification waitUntilDone:YES];
        return;
    }

    [[del managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
}
4

1 に答える 1

0

今日まで、何が起こっているのか正確にはわかりませんでした。最後に、プロジェクトを再起動し、このチュートリアルのようにゼロから設計しました。私は過去に参考のためにそれを使用していましたが、どういうわけか彼らのコードを完全に採用して動作させる必要がありました.

于 2012-09-25T00:47:52.207 に答える